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.ActionableDynamicQuery;
020 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021 import com.liferay.portal.kernel.dao.orm.Property;
022 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
023 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
024 import com.liferay.portal.kernel.dao.orm.QueryUtil;
025 import com.liferay.portal.kernel.diff.DiffHtmlUtil;
026 import com.liferay.portal.kernel.exception.PortalException;
027 import com.liferay.portal.kernel.exception.SystemException;
028 import com.liferay.portal.kernel.json.JSONFactoryUtil;
029 import com.liferay.portal.kernel.json.JSONObject;
030 import com.liferay.portal.kernel.language.LanguageUtil;
031 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
032 import com.liferay.portal.kernel.log.Log;
033 import com.liferay.portal.kernel.log.LogFactoryUtil;
034 import com.liferay.portal.kernel.notifications.UserNotificationDefinition;
035 import com.liferay.portal.kernel.portlet.PortletRequestModel;
036 import com.liferay.portal.kernel.repository.model.FileEntry;
037 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
038 import com.liferay.portal.kernel.search.BaseModelSearchResult;
039 import com.liferay.portal.kernel.search.Field;
040 import com.liferay.portal.kernel.search.Hits;
041 import com.liferay.portal.kernel.search.Indexable;
042 import com.liferay.portal.kernel.search.IndexableType;
043 import com.liferay.portal.kernel.search.Indexer;
044 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
045 import com.liferay.portal.kernel.search.QueryConfig;
046 import com.liferay.portal.kernel.search.SearchContext;
047 import com.liferay.portal.kernel.search.SearchException;
048 import com.liferay.portal.kernel.search.Sort;
049 import com.liferay.portal.kernel.systemevent.SystemEvent;
050 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
051 import com.liferay.portal.kernel.util.ArrayUtil;
052 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
053 import com.liferay.portal.kernel.util.CharPool;
054 import com.liferay.portal.kernel.util.Constants;
055 import com.liferay.portal.kernel.util.ContentTypes;
056 import com.liferay.portal.kernel.util.FileUtil;
057 import com.liferay.portal.kernel.util.GetterUtil;
058 import com.liferay.portal.kernel.util.HtmlUtil;
059 import com.liferay.portal.kernel.util.HttpUtil;
060 import com.liferay.portal.kernel.util.ListUtil;
061 import com.liferay.portal.kernel.util.LocaleUtil;
062 import com.liferay.portal.kernel.util.LocalizationUtil;
063 import com.liferay.portal.kernel.util.MathUtil;
064 import com.liferay.portal.kernel.util.ObjectValuePair;
065 import com.liferay.portal.kernel.util.OrderByComparator;
066 import com.liferay.portal.kernel.util.ParamUtil;
067 import com.liferay.portal.kernel.util.PropsKeys;
068 import com.liferay.portal.kernel.util.StringBundler;
069 import com.liferay.portal.kernel.util.StringPool;
070 import com.liferay.portal.kernel.util.StringUtil;
071 import com.liferay.portal.kernel.util.Time;
072 import com.liferay.portal.kernel.util.UnicodeProperties;
073 import com.liferay.portal.kernel.util.Validator;
074 import com.liferay.portal.kernel.workflow.WorkflowConstants;
075 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
076 import com.liferay.portal.kernel.xml.Document;
077 import com.liferay.portal.kernel.xml.DocumentException;
078 import com.liferay.portal.kernel.xml.Element;
079 import com.liferay.portal.kernel.xml.Node;
080 import com.liferay.portal.kernel.xml.SAXReaderUtil;
081 import com.liferay.portal.kernel.xml.XPath;
082 import com.liferay.portal.model.Company;
083 import com.liferay.portal.model.Group;
084 import com.liferay.portal.model.Image;
085 import com.liferay.portal.model.ResourceConstants;
086 import com.liferay.portal.model.SystemEventConstants;
087 import com.liferay.portal.model.User;
088 import com.liferay.portal.service.ServiceContext;
089 import com.liferay.portal.service.ServiceContextUtil;
090 import com.liferay.portal.servlet.filters.cache.CacheUtil;
091 import com.liferay.portal.theme.ThemeDisplay;
092 import com.liferay.portal.util.PortalUtil;
093 import com.liferay.portal.util.PortletKeys;
094 import com.liferay.portal.util.PrefsPropsUtil;
095 import com.liferay.portal.util.PropsValues;
096 import com.liferay.portal.util.SubscriptionSender;
097 import com.liferay.portal.webserver.WebServerServletTokenUtil;
098 import com.liferay.portlet.asset.model.AssetEntry;
099 import com.liferay.portlet.asset.model.AssetLink;
100 import com.liferay.portlet.asset.model.AssetLinkConstants;
101 import com.liferay.portlet.documentlibrary.util.DLUtil;
102 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
103 import com.liferay.portlet.dynamicdatamapping.StorageFieldNameException;
104 import com.liferay.portlet.dynamicdatamapping.StorageFieldRequiredException;
105 import com.liferay.portlet.dynamicdatamapping.StructureDefinitionException;
106 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
107 import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
108 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
109 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
110 import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
111 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
112 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
113 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
114 import com.liferay.portlet.journal.ArticleContentException;
115 import com.liferay.portlet.journal.ArticleDisplayDateException;
116 import com.liferay.portlet.journal.ArticleExpirationDateException;
117 import com.liferay.portlet.journal.ArticleIdException;
118 import com.liferay.portlet.journal.ArticleReviewDateException;
119 import com.liferay.portlet.journal.ArticleSmallImageNameException;
120 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
121 import com.liferay.portlet.journal.ArticleTitleException;
122 import com.liferay.portlet.journal.ArticleTypeException;
123 import com.liferay.portlet.journal.ArticleVersionException;
124 import com.liferay.portlet.journal.DuplicateArticleIdException;
125 import com.liferay.portlet.journal.InvalidDDMStructureException;
126 import com.liferay.portlet.journal.NoSuchArticleException;
127 import com.liferay.portlet.journal.model.JournalArticle;
128 import com.liferay.portlet.journal.model.JournalArticleConstants;
129 import com.liferay.portlet.journal.model.JournalArticleDisplay;
130 import com.liferay.portlet.journal.model.JournalArticleResource;
131 import com.liferay.portlet.journal.model.JournalFolder;
132 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
133 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
134 import com.liferay.portlet.journal.social.JournalActivityKeys;
135 import com.liferay.portlet.journal.util.JournalUtil;
136 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
137 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
138 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
139 import com.liferay.portlet.social.model.SocialActivityConstants;
140 import com.liferay.portlet.trash.model.TrashEntry;
141 import com.liferay.portlet.trash.model.TrashVersion;
142 import com.liferay.portlet.trash.util.TrashUtil;
143
144 import java.io.File;
145 import java.io.IOException;
146 import java.io.Serializable;
147
148 import java.util.ArrayList;
149 import java.util.Calendar;
150 import java.util.Date;
151 import java.util.HashMap;
152 import java.util.HashSet;
153 import java.util.LinkedHashMap;
154 import java.util.List;
155 import java.util.Locale;
156 import java.util.Map;
157 import java.util.Set;
158
159 import javax.portlet.PortletPreferences;
160
161
190 public class JournalArticleLocalServiceImpl
191 extends JournalArticleLocalServiceBaseImpl {
192
193
273 @Indexable(type = IndexableType.REINDEX)
274 @Override
275 public JournalArticle addArticle(
276 long userId, long groupId, long folderId, long classNameId,
277 long classPK, String articleId, boolean autoArticleId,
278 double version, Map<Locale, String> titleMap,
279 Map<Locale, String> descriptionMap, String content, String type,
280 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
281 int displayDateMonth, int displayDateDay, int displayDateYear,
282 int displayDateHour, int displayDateMinute, int expirationDateMonth,
283 int expirationDateDay, int expirationDateYear,
284 int expirationDateHour, int expirationDateMinute,
285 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
286 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
287 boolean neverReview, boolean indexable, boolean smallImage,
288 String smallImageURL, File smallImageFile,
289 Map<String, byte[]> images, String articleURL,
290 ServiceContext serviceContext)
291 throws PortalException {
292
293
294
295 User user = userPersistence.findByPrimaryKey(userId);
296 articleId = StringUtil.toUpperCase(articleId.trim());
297
298 Date displayDate = null;
299 Date expirationDate = null;
300 Date reviewDate = null;
301
302 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
303 displayDate = PortalUtil.getDate(
304 displayDateMonth, displayDateDay, displayDateYear,
305 displayDateHour, displayDateMinute, user.getTimeZone(),
306 ArticleDisplayDateException.class);
307
308 if (!neverExpire) {
309 expirationDate = PortalUtil.getDate(
310 expirationDateMonth, expirationDateDay, expirationDateYear,
311 expirationDateHour, expirationDateMinute,
312 user.getTimeZone(), ArticleExpirationDateException.class);
313 }
314
315 if (!neverReview) {
316 reviewDate = PortalUtil.getDate(
317 reviewDateMonth, reviewDateDay, reviewDateYear,
318 reviewDateHour, reviewDateMinute, user.getTimeZone(),
319 ArticleReviewDateException.class);
320 }
321 }
322
323 byte[] smallImageBytes = null;
324
325 try {
326 smallImageBytes = FileUtil.getBytes(smallImageFile);
327 }
328 catch (IOException ioe) {
329 }
330
331 Date now = new Date();
332
333 validateDDMStructureId(groupId, folderId, ddmStructureKey);
334
335 validate(
336 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
337 version, titleMap, content, type, ddmStructureKey, ddmTemplateKey,
338 expirationDate, smallImage, smallImageURL, smallImageFile,
339 smallImageBytes, serviceContext);
340
341 if (autoArticleId) {
342 articleId = String.valueOf(counterLocalService.increment());
343 }
344
345 serviceContext.setAttribute("articleId", articleId);
346
347 long id = counterLocalService.increment();
348
349 String articleResourceUuid = GetterUtil.getString(
350 serviceContext.getAttribute("articleResourceUuid"));
351
352 long resourcePrimKey =
353 journalArticleResourceLocalService.getArticleResourcePrimKey(
354 articleResourceUuid, groupId, articleId);
355
356 JournalArticle article = journalArticlePersistence.create(id);
357
358 Locale locale = getArticleDefaultLocale(content, serviceContext);
359
360 String title = titleMap.get(locale);
361
362 content = format(
363 user, groupId, articleId, version, false, content, ddmStructureKey,
364 images);
365
366 article.setUuid(serviceContext.getUuid());
367 article.setResourcePrimKey(resourcePrimKey);
368 article.setGroupId(groupId);
369 article.setCompanyId(user.getCompanyId());
370 article.setUserId(user.getUserId());
371 article.setUserName(user.getFullName());
372 article.setCreateDate(serviceContext.getCreateDate(now));
373 article.setModifiedDate(serviceContext.getModifiedDate(now));
374 article.setFolderId(folderId);
375 article.setClassNameId(classNameId);
376 article.setClassPK(classPK);
377 article.setTreePath(article.buildTreePath());
378 article.setArticleId(articleId);
379 article.setVersion(version);
380 article.setTitleMap(titleMap, locale);
381 article.setUrlTitle(
382 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
383 article.setDescriptionMap(descriptionMap, locale);
384 article.setContent(content);
385 article.setType(type);
386 article.setStructureId(ddmStructureKey);
387 article.setTemplateId(ddmTemplateKey);
388 article.setLayoutUuid(layoutUuid);
389 article.setDisplayDate(displayDate);
390 article.setExpirationDate(expirationDate);
391 article.setReviewDate(reviewDate);
392 article.setIndexable(indexable);
393 article.setSmallImage(smallImage);
394 article.setSmallImageId(counterLocalService.increment());
395 article.setSmallImageURL(smallImageURL);
396
397 if ((expirationDate == null) || expirationDate.after(now)) {
398 article.setStatus(WorkflowConstants.STATUS_DRAFT);
399 }
400 else {
401 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
402 }
403
404 article.setStatusByUserId(userId);
405 article.setStatusDate(serviceContext.getModifiedDate(now));
406 article.setExpandoBridgeAttributes(serviceContext);
407
408 journalArticlePersistence.update(article);
409
410
411
412 if (serviceContext.isAddGroupPermissions() ||
413 serviceContext.isAddGuestPermissions()) {
414
415 addArticleResources(
416 article, serviceContext.isAddGroupPermissions(),
417 serviceContext.isAddGuestPermissions());
418 }
419 else {
420 addArticleResources(
421 article, serviceContext.getGroupPermissions(),
422 serviceContext.getGuestPermissions());
423 }
424
425
426
427 saveImages(
428 smallImage, article.getSmallImageId(), smallImageFile,
429 smallImageBytes);
430
431
432
433 updateAsset(
434 userId, article, serviceContext.getAssetCategoryIds(),
435 serviceContext.getAssetTagNames(),
436 serviceContext.getAssetLinkEntryIds());
437
438
439
440 if (classNameLocalService.getClassNameId(DDMStructure.class) ==
441 classNameId) {
442
443 updateDDMStructurePredefinedValues(
444 classPK, content, serviceContext);
445 }
446
447
448
449 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
450 mbMessageLocalService.addDiscussionMessage(
451 userId, article.getUserName(), groupId,
452 JournalArticle.class.getName(), resourcePrimKey,
453 WorkflowConstants.ACTION_PUBLISH);
454 }
455
456
457
458 PortletPreferences preferences =
459 ServiceContextUtil.getPortletPreferences(serviceContext);
460
461 articleURL = buildArticleURL(articleURL, groupId, folderId, articleId);
462
463 serviceContext.setAttribute("articleURL", articleURL);
464
465 sendEmail(
466 article, articleURL, preferences, "requested", serviceContext);
467
468
469
470 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
471 startWorkflowInstance(userId, article, serviceContext);
472 }
473 else {
474 updateStatus(
475 userId, article, WorkflowConstants.STATUS_APPROVED, null,
476 serviceContext, new HashMap<String, Serializable>());
477 }
478
479 return journalArticlePersistence.findByPrimaryKey(article.getId());
480 }
481
482
508 @Override
509 public JournalArticle addArticle(
510 long userId, long groupId, long folderId,
511 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
512 String content, String ddmStructureKey, String ddmTemplateKey,
513 ServiceContext serviceContext)
514 throws PortalException {
515
516 User user = userPersistence.findByPrimaryKey(userId);
517
518 Calendar calendar = CalendarFactoryUtil.getCalendar(user.getTimeZone());
519
520 int displayDateMonth = calendar.get(Calendar.MONTH);
521 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
522 int displayDateYear = calendar.get(Calendar.YEAR);
523 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
524 int displayDateMinute = calendar.get(Calendar.MINUTE);
525
526 return journalArticleLocalService.addArticle(
527 userId, groupId, folderId,
528 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
529 true, 1, titleMap, descriptionMap, content, "general",
530 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
531 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
532 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
533 null, null, serviceContext);
534 }
535
536
545 @Override
546 public void addArticleResources(
547 JournalArticle article, boolean addGroupPermissions,
548 boolean addGuestPermissions)
549 throws PortalException {
550
551 resourceLocalService.addResources(
552 article.getCompanyId(), article.getGroupId(), article.getUserId(),
553 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
554 addGroupPermissions, addGuestPermissions);
555 }
556
557
565 @Override
566 public void addArticleResources(
567 JournalArticle article, String[] groupPermissions,
568 String[] guestPermissions)
569 throws PortalException {
570
571 resourceLocalService.addModelResources(
572 article.getCompanyId(), article.getGroupId(), article.getUserId(),
573 JournalArticle.class.getName(), article.getResourcePrimKey(),
574 groupPermissions, guestPermissions);
575 }
576
577
586 @Override
587 public void addArticleResources(
588 long groupId, String articleId, boolean addGroupPermissions,
589 boolean addGuestPermissions)
590 throws PortalException {
591
592 JournalArticle article = getLatestArticle(groupId, articleId);
593
594 addArticleResources(article, addGroupPermissions, addGuestPermissions);
595 }
596
597
607 @Override
608 public void addArticleResources(
609 long groupId, String articleId, String[] groupPermissions,
610 String[] guestPermissions)
611 throws PortalException {
612
613 JournalArticle article = getLatestArticle(groupId, articleId);
614
615 addArticleResources(article, groupPermissions, guestPermissions);
616 }
617
618
630 @Override
631 public JournalArticle checkArticleResourcePrimKey(
632 long groupId, String articleId, double version)
633 throws PortalException {
634
635 JournalArticle article = journalArticlePersistence.findByG_A_V(
636 groupId, articleId, version);
637
638 if (article.getResourcePrimKey() > 0) {
639 return article;
640 }
641
642 long resourcePrimKey =
643 journalArticleResourceLocalService.getArticleResourcePrimKey(
644 groupId, articleId);
645
646 article.setResourcePrimKey(resourcePrimKey);
647
648 journalArticlePersistence.update(article);
649
650 return article;
651 }
652
653
659 @Override
660 public void checkArticles() throws PortalException {
661 Date now = new Date();
662
663 checkArticlesByExpirationDate(now);
664
665 checkArticlesByReviewDate(now);
666
667 checkArticlesByDisplayDate(now);
668
669 _previousCheckDate = now;
670 }
671
672
683 @Override
684 public void checkNewLine(long groupId, String articleId, double version)
685 throws PortalException {
686
687 JournalArticle article = journalArticlePersistence.findByG_A_V(
688 groupId, articleId, version);
689
690 String content = GetterUtil.getString(article.getContent());
691
692 if (content.contains("\\n")) {
693 content = StringUtil.replace(
694 content, new String[] {"\\n", "\\r"},
695 new String[] {"\n", "\r"});
696
697 article.setContent(content);
698
699 journalArticlePersistence.update(article);
700 }
701 }
702
703
715 @Override
716 public void checkStructure(long groupId, String articleId, double version)
717 throws PortalException {
718
719 JournalArticle article = journalArticlePersistence.findByG_A_V(
720 groupId, articleId, version);
721
722 checkStructure(article);
723 }
724
725
740 @Indexable(type = IndexableType.REINDEX)
741 @Override
742 public JournalArticle copyArticle(
743 long userId, long groupId, String oldArticleId, String newArticleId,
744 boolean autoArticleId, double version)
745 throws PortalException {
746
747
748
749 User user = userPersistence.findByPrimaryKey(userId);
750 oldArticleId = StringUtil.toUpperCase(oldArticleId.trim());
751 newArticleId = StringUtil.toUpperCase(newArticleId.trim());
752 Date now = new Date();
753
754 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
755 groupId, oldArticleId, version);
756
757 if (autoArticleId) {
758 newArticleId = String.valueOf(counterLocalService.increment());
759 }
760 else {
761 validate(newArticleId);
762
763 if (journalArticlePersistence.countByG_A(
764 groupId, newArticleId) > 0) {
765
766 StringBundler sb = new StringBundler(5);
767
768 sb.append("{groupId=");
769 sb.append(groupId);
770 sb.append(", articleId=");
771 sb.append(newArticleId);
772 sb.append("}");
773
774 throw new DuplicateArticleIdException(sb.toString());
775 }
776 }
777
778 long id = counterLocalService.increment();
779
780 long resourcePrimKey =
781 journalArticleResourceLocalService.getArticleResourcePrimKey(
782 groupId, newArticleId);
783
784 JournalArticle newArticle = journalArticlePersistence.create(id);
785
786 newArticle.setResourcePrimKey(resourcePrimKey);
787 newArticle.setGroupId(groupId);
788 newArticle.setCompanyId(user.getCompanyId());
789 newArticle.setUserId(user.getUserId());
790 newArticle.setUserName(user.getFullName());
791 newArticle.setCreateDate(now);
792 newArticle.setModifiedDate(now);
793 newArticle.setFolderId(oldArticle.getFolderId());
794 newArticle.setTreePath(oldArticle.getTreePath());
795 newArticle.setArticleId(newArticleId);
796 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
797 newArticle.setTitle(oldArticle.getTitle());
798 newArticle.setUrlTitle(
799 getUniqueUrlTitle(
800 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
801 newArticle.setDescription(oldArticle.getDescription());
802
803 try {
804 copyArticleImages(oldArticle, newArticle);
805 }
806 catch (Exception e) {
807 newArticle.setContent(oldArticle.getContent());
808 }
809
810 newArticle.setType(oldArticle.getType());
811 newArticle.setStructureId(oldArticle.getStructureId());
812 newArticle.setTemplateId(oldArticle.getTemplateId());
813 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
814 newArticle.setDisplayDate(oldArticle.getDisplayDate());
815 newArticle.setExpirationDate(oldArticle.getExpirationDate());
816 newArticle.setReviewDate(oldArticle.getReviewDate());
817 newArticle.setIndexable(oldArticle.isIndexable());
818 newArticle.setSmallImage(oldArticle.isSmallImage());
819 newArticle.setSmallImageId(counterLocalService.increment());
820 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
821
822 if (oldArticle.isPending() ||
823 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
824 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
825
826 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
827 }
828 else {
829 newArticle.setStatus(oldArticle.getStatus());
830 }
831
832 newArticle.setExpandoBridgeAttributes(oldArticle);
833
834 journalArticlePersistence.update(newArticle);
835
836
837
838 addArticleResources(newArticle, true, true);
839
840
841
842 if (oldArticle.isSmallImage()) {
843 Image image = imageLocalService.fetchImage(
844 oldArticle.getSmallImageId());
845
846 if (image != null) {
847 byte[] smallImageBytes = image.getTextObj();
848
849 imageLocalService.updateImage(
850 newArticle.getSmallImageId(), smallImageBytes);
851 }
852 }
853
854
855
856 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
857 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
858 String[] assetTagNames = assetTagLocalService.getTagNames(
859 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
860
861 AssetEntry oldAssetEntry = assetEntryLocalService.getEntry(
862 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
863
864 List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
865 oldAssetEntry.getEntryId());
866
867 long[] assetLinkEntryIds = ListUtil.toLongArray(
868 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
869
870 updateAsset(
871 userId, newArticle, assetCategoryIds, assetTagNames,
872 assetLinkEntryIds);
873
874 return newArticle;
875 }
876
877
884 @Override
885 @SystemEvent(
886 action = SystemEventConstants.ACTION_SKIP, send = false,
887 type = SystemEventConstants.TYPE_DELETE)
888 public JournalArticle deleteArticle(JournalArticle article)
889 throws PortalException {
890
891 return journalArticleLocalService.deleteArticle(
892 article, StringPool.BLANK, null);
893 }
894
895
909 @Indexable(type = IndexableType.DELETE)
910 @Override
911 @SystemEvent(
912 action = SystemEventConstants.ACTION_SKIP, send = false,
913 type = SystemEventConstants.TYPE_DELETE)
914 public JournalArticle deleteArticle(
915 JournalArticle article, String articleURL,
916 ServiceContext serviceContext)
917 throws PortalException {
918
919 JournalArticleResource articleResource =
920 journalArticleResourceLocalService.fetchArticleResource(
921 article.getGroupId(), article.getArticleId());
922
923 if (article.isApproved() &&
924 isLatestVersion(
925 article.getGroupId(), article.getArticleId(),
926 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
927
928 updatePreviousApprovedArticle(article);
929 }
930
931
932
933 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
934 PortletPreferences preferences =
935 ServiceContextUtil.getPortletPreferences(serviceContext);
936
937 if ((preferences != null) && !article.isApproved() &&
938 isLatestVersion(
939 article.getGroupId(), article.getArticleId(),
940 article.getVersion())) {
941
942 articleURL = buildArticleURL(
943 articleURL, article.getGroupId(), article.getFolderId(),
944 article.getArticleId());
945
946 sendEmail(
947 article, articleURL, preferences, "denied", serviceContext);
948 }
949 }
950
951
952
953 String articleId = article.getArticleId();
954
955 if (article.isInTrash()) {
956 articleId = TrashUtil.getOriginalTitle(article.getArticleId());
957 }
958
959 journalArticleImageLocalService.deleteImages(
960 article.getGroupId(), articleId, article.getVersion());
961
962
963
964 expandoRowLocalService.deleteRows(article.getId());
965
966
967
968 if (article.isInTrash()) {
969 TrashEntry trashEntry = article.getTrashEntry();
970
971 if (trashEntry != null) {
972 trashVersionLocalService.deleteTrashVersion(
973 JournalArticle.class.getName(), article.getId());
974 }
975 }
976
977
978
979 if (!article.isDraft()) {
980 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
981 article.getCompanyId(), article.getGroupId(),
982 JournalArticle.class.getName(), article.getId());
983 }
984
985 int articlesCount = journalArticlePersistence.countByG_A(
986 article.getGroupId(), article.getArticleId());
987
988 if (articlesCount == 1) {
989
990
991
992 ratingsStatsLocalService.deleteStats(
993 JournalArticle.class.getName(), article.getResourcePrimKey());
994
995
996
997 mbMessageLocalService.deleteDiscussionMessages(
998 JournalArticle.class.getName(), article.getResourcePrimKey());
999
1000
1001
1002 assetEntryLocalService.deleteEntry(
1003 JournalArticle.class.getName(), article.getResourcePrimKey());
1004
1005
1006
1007 journalContentSearchLocalService.deleteArticleContentSearches(
1008 article.getGroupId(), article.getArticleId());
1009
1010
1011
1012 imageLocalService.deleteImage(article.getSmallImageId());
1013
1014
1015
1016 trashEntryLocalService.deleteEntry(
1017 JournalArticle.class.getName(), article.getResourcePrimKey());
1018
1019
1020
1021 resourceLocalService.deleteResource(
1022 article.getCompanyId(), JournalArticle.class.getName(),
1023 ResourceConstants.SCOPE_INDIVIDUAL,
1024 article.getResourcePrimKey());
1025
1026
1027
1028 if (articleResource != null) {
1029 journalArticleResourceLocalService.deleteJournalArticleResource(
1030 articleResource);
1031 }
1032 }
1033
1034
1035
1036 journalArticlePersistence.remove(article);
1037
1038
1039
1040 if (articleResource != null) {
1041 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1042
1043 extraDataJSONObject.put("uuid", article.getUuid());
1044 extraDataJSONObject.put("version", article.getVersion());
1045
1046 systemEventLocalService.addSystemEvent(
1047 0, article.getGroupId(), article.getModelClassName(),
1048 article.getPrimaryKey(), articleResource.getUuid(), null,
1049 SystemEventConstants.TYPE_DELETE,
1050 extraDataJSONObject.toString());
1051 }
1052
1053 return article;
1054 }
1055
1056
1072 @Override
1073 public JournalArticle deleteArticle(
1074 long groupId, String articleId, double version, String articleURL,
1075 ServiceContext serviceContext)
1076 throws PortalException {
1077
1078 JournalArticle article = journalArticlePersistence.findByG_A_V(
1079 groupId, articleId, version);
1080
1081 return journalArticleLocalService.deleteArticle(
1082 article, articleURL, serviceContext);
1083 }
1084
1085
1097 @Override
1098 public void deleteArticle(
1099 long groupId, String articleId, ServiceContext serviceContext)
1100 throws PortalException {
1101
1102 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1103
1104 JournalArticleResource articleResource =
1105 journalArticleResourceLocalService.fetchArticleResource(
1106 groupId, articleId);
1107
1108 try {
1109 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1110 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1111 new ArticleVersionComparator(true));
1112
1113 for (JournalArticle article : articles) {
1114 journalArticleLocalService.deleteArticle(
1115 article, null, serviceContext);
1116 }
1117 }
1118 finally {
1119 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1120 }
1121
1122 if (articleResource != null) {
1123 systemEventLocalService.addSystemEvent(
1124 0, groupId, JournalArticle.class.getName(),
1125 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1126 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1127 }
1128 }
1129
1130
1136 @Override
1137 public void deleteArticles(long groupId) throws PortalException {
1138 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1139
1140 List<JournalArticleResource> articleResources =
1141 new ArrayList<JournalArticleResource>();
1142
1143 try {
1144 JournalArticleResource articleResource = null;
1145
1146 for (JournalArticle article :
1147 journalArticlePersistence.findByGroupId(groupId)) {
1148
1149 if ((articleResource == null) ||
1150 (articleResource.getPrimaryKey() !=
1151 article.getResourcePrimKey())) {
1152
1153 articleResource =
1154 journalArticleResourceLocalService.getArticleResource(
1155 article.getResourcePrimKey());
1156
1157 articleResources.add(articleResource);
1158 }
1159
1160 journalArticleLocalService.deleteArticle(article, null, null);
1161 }
1162 }
1163 finally {
1164 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1165 }
1166
1167 for (JournalArticleResource articleResource : articleResources) {
1168 systemEventLocalService.addSystemEvent(
1169 0, groupId, JournalArticle.class.getName(),
1170 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1171 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1172 }
1173 }
1174
1175
1183 @Override
1184 public void deleteArticles(long groupId, long folderId)
1185 throws PortalException {
1186
1187 deleteArticles(groupId, folderId, true);
1188 }
1189
1190
1200 @Override
1201 public void deleteArticles(
1202 long groupId, long folderId, boolean includeTrashedEntries)
1203 throws PortalException {
1204
1205 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1206
1207 List<JournalArticleResource> articleResources =
1208 new ArrayList<JournalArticleResource>();
1209
1210 try {
1211 JournalArticleResource articleResource = null;
1212
1213 for (JournalArticle article :
1214 journalArticlePersistence.findByG_F(groupId, folderId)) {
1215
1216 if ((articleResource == null) ||
1217 (articleResource.getPrimaryKey() !=
1218 article.getResourcePrimKey())) {
1219
1220 articleResource =
1221 journalArticleResourceLocalService.getArticleResource(
1222 article.getResourcePrimKey());
1223
1224 articleResources.add(articleResource);
1225 }
1226
1227 if (includeTrashedEntries || !article.isInTrashExplicitly()) {
1228 journalArticleLocalService.deleteArticle(
1229 article, null, null);
1230 }
1231 else {
1232 articleResources.remove(articleResource);
1233 }
1234 }
1235 }
1236 finally {
1237 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1238 }
1239
1240 for (JournalArticleResource articleResource : articleResources) {
1241 systemEventLocalService.addSystemEvent(
1242 0, groupId, JournalArticle.class.getName(),
1243 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1244 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1245 }
1246 }
1247
1248
1256 @Override
1257 public void deleteLayoutArticleReferences(long groupId, String layoutUuid) {
1258 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1259 groupId, layoutUuid);
1260
1261 for (JournalArticle article : articles) {
1262 article.setLayoutUuid(StringPool.BLANK);
1263
1264 journalArticlePersistence.update(article);
1265 }
1266 }
1267
1268
1290 @Indexable(type = IndexableType.REINDEX)
1291 @Override
1292 public JournalArticle expireArticle(
1293 long userId, long groupId, String articleId, double version,
1294 String articleURL, ServiceContext serviceContext)
1295 throws PortalException {
1296
1297 return updateStatus(
1298 userId, groupId, articleId, version,
1299 WorkflowConstants.STATUS_EXPIRED, articleURL,
1300 new HashMap<String, Serializable>(), serviceContext);
1301 }
1302
1303
1325 @Override
1326 public void expireArticle(
1327 long userId, long groupId, String articleId, String articleURL,
1328 ServiceContext serviceContext)
1329 throws PortalException {
1330
1331 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1332 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1333 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1334 new ArticleVersionComparator(true));
1335
1336 for (JournalArticle article : articles) {
1337 journalArticleLocalService.expireArticle(
1338 userId, groupId, article.getArticleId(),
1339 article.getVersion(), articleURL, serviceContext);
1340 }
1341 }
1342 else {
1343 JournalArticle article = getLatestArticle(
1344 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1345
1346 journalArticleLocalService.expireArticle(
1347 userId, groupId, article.getArticleId(), article.getVersion(),
1348 articleURL, serviceContext);
1349 }
1350 }
1351
1352
1363 @Override
1364 public JournalArticle fetchArticle(
1365 long groupId, String articleId, double version) {
1366
1367 return journalArticlePersistence.fetchByG_A_V(
1368 groupId, articleId, version);
1369 }
1370
1371 @Override
1372 public JournalArticle fetchLatestArticle(long resourcePrimKey) {
1373 return fetchLatestArticle(
1374 resourcePrimKey, WorkflowConstants.STATUS_ANY);
1375 }
1376
1377 @Override
1378 public JournalArticle fetchLatestArticle(long resourcePrimKey, int status) {
1379 return fetchLatestArticle(resourcePrimKey, status, true);
1380 }
1381
1382
1400 @Override
1401 public JournalArticle fetchLatestArticle(
1402 long resourcePrimKey, int status, boolean preferApproved) {
1403
1404 JournalArticle article = null;
1405
1406 OrderByComparator<JournalArticle> orderByComparator =
1407 new ArticleVersionComparator();
1408
1409 if (status == WorkflowConstants.STATUS_ANY) {
1410 if (preferApproved) {
1411 article = journalArticlePersistence.fetchByR_ST_First(
1412 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1413 orderByComparator);
1414 }
1415
1416 if (article == null) {
1417 article =
1418 journalArticlePersistence.fetchByResourcePrimKey_First(
1419 resourcePrimKey, orderByComparator);
1420 }
1421 }
1422 else {
1423 article = journalArticlePersistence.fetchByR_ST_First(
1424 resourcePrimKey, status, orderByComparator);
1425 }
1426
1427 return article;
1428 }
1429
1430 @Override
1431 public JournalArticle fetchLatestArticle(
1432 long resourcePrimKey, int[] statuses) {
1433
1434 OrderByComparator<JournalArticle> orderByComparator =
1435 new ArticleVersionComparator();
1436
1437 List<JournalArticle> articles = journalArticlePersistence.findByR_ST(
1438 resourcePrimKey, statuses, 0, 1, orderByComparator);
1439
1440 if (!articles.isEmpty()) {
1441 return articles.get(0);
1442 }
1443
1444 return null;
1445 }
1446
1447
1459 @Override
1460 public JournalArticle fetchLatestArticle(
1461 long groupId, String articleId, int status) {
1462
1463 OrderByComparator<JournalArticle> orderByComparator =
1464 new ArticleVersionComparator();
1465
1466 if (status == WorkflowConstants.STATUS_ANY) {
1467 return journalArticlePersistence.fetchByG_A_NotST_First(
1468 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
1469 orderByComparator);
1470 }
1471
1472 return journalArticlePersistence.fetchByG_A_ST_First(
1473 groupId, articleId, status, orderByComparator);
1474 }
1475
1476
1485 @Override
1486 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey) {
1487 OrderByComparator<JournalArticle> orderByComparator =
1488 new ArticleVersionComparator();
1489
1490 int[] statuses = new int[] {
1491 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1492 };
1493
1494 List<JournalArticle> articles = journalArticlePersistence.findByR_I_S(
1495 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1496
1497 if (articles.isEmpty()) {
1498 return null;
1499 }
1500
1501 return articles.get(0);
1502 }
1503
1504
1512 @Override
1513 public JournalArticle getArticle(long id) throws PortalException {
1514 return journalArticlePersistence.findByPrimaryKey(id);
1515 }
1516
1517
1528 @Override
1529 public JournalArticle getArticle(long groupId, String articleId)
1530 throws PortalException {
1531
1532
1533
1534
1535 try {
1536 return getLatestArticle(
1537 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1538 }
1539 catch (NoSuchArticleException nsae) {
1540 return getLatestArticle(
1541 groupId, articleId, WorkflowConstants.STATUS_ANY);
1542 }
1543 }
1544
1545
1556 @Override
1557 public JournalArticle getArticle(
1558 long groupId, String articleId, double version)
1559 throws PortalException {
1560
1561 return journalArticlePersistence.findByG_A_V(
1562 groupId, articleId, version);
1563 }
1564
1565
1582 @Override
1583 public JournalArticle getArticle(
1584 long groupId, String className, long classPK)
1585 throws PortalException {
1586
1587 long classNameId = classNameLocalService.getClassNameId(className);
1588
1589 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1590 groupId, classNameId, classPK);
1591
1592 if (articles.isEmpty()) {
1593 throw new NoSuchArticleException(
1594 "No approved JournalArticle exists with the key {groupId=" +
1595 groupId + ", className=" + className + ", classPK=" +
1596 classPK + "}");
1597 }
1598
1599 return articles.get(0);
1600 }
1601
1602
1612 @Override
1613 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1614 throws PortalException {
1615
1616
1617
1618
1619 try {
1620 return getLatestArticleByUrlTitle(
1621 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1622 }
1623 catch (NoSuchArticleException nsae) {
1624 return getLatestArticleByUrlTitle(
1625 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1626 }
1627 }
1628
1629
1645 @Override
1646 public String getArticleContent(
1647 JournalArticle article, String ddmTemplateKey, String viewMode,
1648 String languageId, PortletRequestModel portletRequestModel,
1649 ThemeDisplay themeDisplay)
1650 throws PortalException {
1651
1652 JournalArticleDisplay articleDisplay = getArticleDisplay(
1653 article, ddmTemplateKey, viewMode, languageId, 1,
1654 portletRequestModel, themeDisplay);
1655
1656 if (articleDisplay == null) {
1657 return StringPool.BLANK;
1658 }
1659 else {
1660 return articleDisplay.getContent();
1661 }
1662 }
1663
1664
1681 @Deprecated
1682 @Override
1683 public String getArticleContent(
1684 JournalArticle article, String ddmTemplateKey, String viewMode,
1685 String languageId, ThemeDisplay themeDisplay)
1686 throws PortalException {
1687
1688 return getArticleContent(
1689 article, ddmTemplateKey, viewMode, languageId, null, themeDisplay);
1690 }
1691
1692
1710 @Override
1711 public String getArticleContent(
1712 long groupId, String articleId, double version, String viewMode,
1713 String ddmTemplateKey, String languageId,
1714 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
1715 throws PortalException {
1716
1717 JournalArticleDisplay articleDisplay = getArticleDisplay(
1718 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1719 1, portletRequestModel, themeDisplay);
1720
1721 if (articleDisplay == null) {
1722 return StringPool.BLANK;
1723 }
1724 else {
1725 return articleDisplay.getContent();
1726 }
1727 }
1728
1729
1751 @Deprecated
1752 @Override
1753 public String getArticleContent(
1754 long groupId, String articleId, double version, String viewMode,
1755 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1756 throws PortalException {
1757
1758 return getArticleContent(
1759 groupId, articleId, version, viewMode, ddmTemplateKey, languageId,
1760 null, themeDisplay);
1761 }
1762
1763
1781 @Deprecated
1782 @Override
1783 public String getArticleContent(
1784 long groupId, String articleId, double version, String viewMode,
1785 String languageId, ThemeDisplay themeDisplay)
1786 throws PortalException {
1787
1788 return getArticleContent(
1789 groupId, articleId, version, viewMode, null, languageId, null,
1790 themeDisplay);
1791 }
1792
1793
1810 @Override
1811 public String getArticleContent(
1812 long groupId, String articleId, String viewMode,
1813 String ddmTemplateKey, String languageId,
1814 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
1815 throws PortalException {
1816
1817 JournalArticleDisplay articleDisplay = getArticleDisplay(
1818 groupId, articleId, ddmTemplateKey, viewMode, languageId, 1,
1819 portletRequestModel, themeDisplay);
1820
1821 return articleDisplay.getContent();
1822 }
1823
1824
1843 @Deprecated
1844 @Override
1845 public String getArticleContent(
1846 long groupId, String articleId, String viewMode,
1847 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1848 throws PortalException {
1849
1850 return getArticleContent(
1851 groupId, articleId, viewMode, ddmTemplateKey, languageId, null,
1852 themeDisplay);
1853 }
1854
1855
1872 @Deprecated
1873 @Override
1874 public String getArticleContent(
1875 long groupId, String articleId, String viewMode, String languageId,
1876 ThemeDisplay themeDisplay)
1877 throws PortalException {
1878
1879 return getArticleContent(
1880 groupId, articleId, viewMode, null, languageId, null, themeDisplay);
1881 }
1882
1883
1902 @Override
1903 public JournalArticleDisplay getArticleDisplay(
1904 JournalArticle article, String ddmTemplateKey, String viewMode,
1905 String languageId, int page,
1906 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
1907 throws PortalException {
1908
1909 return getArticleDisplay(
1910 article, ddmTemplateKey, viewMode, languageId, page,
1911 portletRequestModel, themeDisplay, false);
1912 }
1913
1914
1935 @Override
1936 public JournalArticleDisplay getArticleDisplay(
1937 long groupId, String articleId, double version,
1938 String ddmTemplateKey, String viewMode, String languageId, int page,
1939 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
1940 throws PortalException {
1941
1942 Date now = new Date();
1943
1944 JournalArticle article = journalArticlePersistence.findByG_A_V(
1945 groupId, articleId, version);
1946
1947 if (article.isExpired()) {
1948 Date expirationDate = article.getExpirationDate();
1949
1950 if ((expirationDate != null) && expirationDate.before(now)) {
1951 return null;
1952 }
1953 }
1954
1955 Date displayDate = article.getDisplayDate();
1956
1957 if (displayDate.after(now)) {
1958 return null;
1959 }
1960
1961 return getArticleDisplay(
1962 article, ddmTemplateKey, viewMode, languageId, page,
1963 portletRequestModel, themeDisplay);
1964 }
1965
1966
1986 @Override
1987 public JournalArticleDisplay getArticleDisplay(
1988 long groupId, String articleId, double version,
1989 String ddmTemplateKey, String viewMode, String languageId,
1990 ThemeDisplay themeDisplay)
1991 throws PortalException {
1992
1993 return getArticleDisplay(
1994 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1995 1, null, themeDisplay);
1996 }
1997
1998
2016 @Override
2017 public JournalArticleDisplay getArticleDisplay(
2018 long groupId, String articleId, String viewMode, String languageId,
2019 int page, PortletRequestModel portletRequestModel,
2020 ThemeDisplay themeDisplay)
2021 throws PortalException {
2022
2023 return getArticleDisplay(
2024 groupId, articleId, null, viewMode, languageId, page,
2025 portletRequestModel, themeDisplay);
2026 }
2027
2028
2048 @Override
2049 public JournalArticleDisplay getArticleDisplay(
2050 long groupId, String articleId, String ddmTemplateKey,
2051 String viewMode, String languageId, int page,
2052 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
2053 throws PortalException {
2054
2055 JournalArticle article = getDisplayArticle(groupId, articleId);
2056
2057 return getArticleDisplay(
2058 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2059 languageId, page, portletRequestModel, themeDisplay);
2060 }
2061
2062
2081 @Override
2082 public JournalArticleDisplay getArticleDisplay(
2083 long groupId, String articleId, String ddmTemplateKey,
2084 String viewMode, String languageId, ThemeDisplay themeDisplay)
2085 throws PortalException {
2086
2087 JournalArticle article = getDisplayArticle(groupId, articleId);
2088
2089 return getArticleDisplay(
2090 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2091 languageId, themeDisplay);
2092 }
2093
2094
2111 @Override
2112 public JournalArticleDisplay getArticleDisplay(
2113 long groupId, String articleId, String viewMode, String languageId,
2114 ThemeDisplay themeDisplay)
2115 throws PortalException {
2116
2117 return getArticleDisplay(
2118 groupId, articleId, null, viewMode, languageId, themeDisplay);
2119 }
2120
2121
2126 @Override
2127 public List<JournalArticle> getArticles() {
2128 return journalArticlePersistence.findAll();
2129 }
2130
2131
2137 @Override
2138 public List<JournalArticle> getArticles(long groupId) {
2139 return journalArticlePersistence.findByGroupId(groupId);
2140 }
2141
2142
2161 @Override
2162 public List<JournalArticle> getArticles(long groupId, int start, int end) {
2163 return journalArticlePersistence.findByGroupId(groupId, start, end);
2164 }
2165
2166
2188 @Override
2189 public List<JournalArticle> getArticles(
2190 long groupId, int start, int end,
2191 OrderByComparator<JournalArticle> obc) {
2192
2193 return journalArticlePersistence.findByGroupId(
2194 groupId, start, end, obc);
2195 }
2196
2197
2204 @Override
2205 public List<JournalArticle> getArticles(long groupId, long folderId) {
2206 return journalArticlePersistence.findByG_F(groupId, folderId);
2207 }
2208
2209
2230 @Override
2231 public List<JournalArticle> getArticles(
2232 long groupId, long folderId, int start, int end) {
2233
2234 return journalArticlePersistence.findByG_F(
2235 groupId, folderId, start, end);
2236 }
2237
2238
2262 @Override
2263 public List<JournalArticle> getArticles(
2264 long groupId, long folderId, int status, int start, int end) {
2265
2266 return journalArticlePersistence.findByG_F_ST(
2267 groupId, folderId, status, start, end);
2268 }
2269
2270
2294 @Override
2295 public List<JournalArticle> getArticles(
2296 long groupId, long folderId, int start, int end,
2297 OrderByComparator<JournalArticle> orderByComparator) {
2298
2299 return journalArticlePersistence.findByG_F(
2300 groupId, folderId, start, end, orderByComparator);
2301 }
2302
2303
2310 @Override
2311 public List<JournalArticle> getArticles(long groupId, String articleId) {
2312 return journalArticlePersistence.findByG_A(groupId, articleId);
2313 }
2314
2315 @Override
2316 public List<JournalArticle> getArticles(
2317 long groupId, String articleId, int start, int end,
2318 OrderByComparator<JournalArticle> orderByComparator) {
2319
2320 return journalArticlePersistence.findByG_A(
2321 groupId, articleId, start, end, orderByComparator);
2322 }
2323
2324
2330 @Override
2331 public List<JournalArticle> getArticlesByResourcePrimKey(
2332 long resourcePrimKey) {
2333
2334 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2335 }
2336
2337
2344 @Override
2345 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId) {
2346 return journalArticlePersistence.findBySmallImageId(smallImageId);
2347 }
2348
2349
2355 @Override
2356 public int getArticlesCount(long groupId) {
2357 return journalArticlePersistence.countByGroupId(groupId);
2358 }
2359
2360
2367 @Override
2368 public int getArticlesCount(long groupId, long folderId) {
2369 return journalArticlePersistence.countByG_F(groupId, folderId);
2370 }
2371
2372
2383 @Override
2384 public int getArticlesCount(long groupId, long folderId, int status) {
2385 return journalArticlePersistence.countByG_F_ST(
2386 groupId, folderId, status);
2387 }
2388
2389 @Override
2390 public int getArticlesCount(long groupId, String articleId) {
2391 return journalArticlePersistence.countByG_A(groupId, articleId);
2392 }
2393
2394
2418 @Override
2419 public List<JournalArticle> getCompanyArticles(
2420 long companyId, double version, int status, int start, int end) {
2421
2422 if (status == WorkflowConstants.STATUS_ANY) {
2423 return journalArticlePersistence.findByC_V(
2424 companyId, version, start, end, new ArticleIDComparator(true));
2425 }
2426 else {
2427 return journalArticlePersistence.findByC_V_ST(
2428 companyId, version, status, start, end,
2429 new ArticleIDComparator(true));
2430 }
2431 }
2432
2433
2456 @Override
2457 public List<JournalArticle> getCompanyArticles(
2458 long companyId, int status, int start, int end) {
2459
2460 if (status == WorkflowConstants.STATUS_ANY) {
2461 return journalArticlePersistence.findByCompanyId(
2462 companyId, start, end, new ArticleIDComparator(true));
2463 }
2464 else {
2465 return journalArticlePersistence.findByC_ST(
2466 companyId, status, start, end, new ArticleIDComparator(true));
2467 }
2468 }
2469
2470
2494 @Override
2495 public int getCompanyArticlesCount(
2496 long companyId, double version, int status, int start, int end) {
2497
2498 if (status == WorkflowConstants.STATUS_ANY) {
2499 return journalArticlePersistence.countByC_V(companyId, version);
2500 }
2501 else {
2502 return journalArticlePersistence.countByC_V_ST(
2503 companyId, version, status);
2504 }
2505 }
2506
2507
2517 @Override
2518 public int getCompanyArticlesCount(long companyId, int status) {
2519 if (status == WorkflowConstants.STATUS_ANY) {
2520 return journalArticlePersistence.countByCompanyId(companyId);
2521 }
2522 else {
2523 return journalArticlePersistence.countByC_ST(companyId, status);
2524 }
2525 }
2526
2527
2539 @Override
2540 public JournalArticle getDisplayArticle(long groupId, String articleId)
2541 throws PortalException {
2542
2543 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2544 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2545
2546 if (articles.isEmpty()) {
2547 throw new NoSuchArticleException(
2548 "No approved JournalArticle exists with the key {groupId=" +
2549 groupId + ", " + "articleId=" + articleId + "}");
2550 }
2551
2552 Date now = new Date();
2553
2554 for (int i = 0; i < articles.size(); i++) {
2555 JournalArticle article = articles.get(i);
2556
2557 Date displayDate = article.getDisplayDate();
2558 Date expirationDate = article.getExpirationDate();
2559
2560 if (((displayDate == null) || displayDate.before(now)) &&
2561 ((expirationDate == null) || expirationDate.after(now))) {
2562
2563 return article;
2564 }
2565 }
2566
2567 return articles.get(0);
2568 }
2569
2570
2582 @Override
2583 public JournalArticle getDisplayArticleByUrlTitle(
2584 long groupId, String urlTitle)
2585 throws PortalException {
2586
2587 List<JournalArticle> articles = null;
2588
2589 OrderByComparator<JournalArticle> orderByComparator =
2590 new ArticleVersionComparator();
2591
2592 articles = journalArticlePersistence.findByG_UT_ST(
2593 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2594 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2595
2596 if (articles.isEmpty()) {
2597 throw new NoSuchArticleException(
2598 "No JournalArticle exists with the key {groupId=" + groupId +
2599 ", urlTitle=" + urlTitle + "}");
2600 }
2601
2602 Date now = new Date();
2603
2604 for (JournalArticle article : articles) {
2605 Date displayDate = article.getDisplayDate();
2606 Date expirationDate = article.getExpirationDate();
2607
2608 if ((displayDate != null) && displayDate.before(now) &&
2609 ((expirationDate == null) || expirationDate.after(now)) ) {
2610
2611 return article;
2612 }
2613 }
2614
2615 return articles.get(0);
2616 }
2617
2618
2626 @Override
2627 public List<JournalArticle> getIndexableArticlesByResourcePrimKey(
2628 long resourcePrimKey) {
2629
2630 return journalArticlePersistence.findByR_I(resourcePrimKey, true);
2631 }
2632
2633
2643 @Override
2644 public JournalArticle getLatestArticle(long resourcePrimKey)
2645 throws PortalException {
2646
2647 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2648 }
2649
2650
2664 @Override
2665 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2666 throws PortalException {
2667
2668 return getLatestArticle(resourcePrimKey, status, true);
2669 }
2670
2671
2690 @Override
2691 public JournalArticle getLatestArticle(
2692 long resourcePrimKey, int status, boolean preferApproved)
2693 throws PortalException {
2694
2695 List<JournalArticle> articles = null;
2696
2697 OrderByComparator<JournalArticle> orderByComparator =
2698 new ArticleVersionComparator();
2699
2700 if (status == WorkflowConstants.STATUS_ANY) {
2701 if (preferApproved) {
2702 articles = journalArticlePersistence.findByR_ST(
2703 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2704 orderByComparator);
2705 }
2706
2707 if (ListUtil.isEmpty(articles)) {
2708 articles = journalArticlePersistence.findByResourcePrimKey(
2709 resourcePrimKey, 0, 1, orderByComparator);
2710 }
2711 }
2712 else {
2713 articles = journalArticlePersistence.findByR_ST(
2714 resourcePrimKey, status, 0, 1, orderByComparator);
2715 }
2716
2717 if (articles.isEmpty()) {
2718 throw new NoSuchArticleException(
2719 "No JournalArticle exists with the key {resourcePrimKey=" +
2720 resourcePrimKey + "}");
2721 }
2722
2723 return articles.get(0);
2724 }
2725
2726
2735 @Override
2736 public JournalArticle getLatestArticle(long groupId, String articleId)
2737 throws PortalException {
2738
2739 return getLatestArticle(
2740 groupId, articleId, WorkflowConstants.STATUS_ANY);
2741 }
2742
2743
2756 @Override
2757 public JournalArticle getLatestArticle(
2758 long groupId, String articleId, int status)
2759 throws PortalException {
2760
2761 return getFirstArticle(
2762 groupId, articleId, status, new ArticleVersionComparator());
2763 }
2764
2765
2782 @Override
2783 public JournalArticle getLatestArticle(
2784 long groupId, String className, long classPK)
2785 throws PortalException {
2786
2787 long classNameId = classNameLocalService.getClassNameId(className);
2788
2789 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2790 groupId, classNameId, classPK, 0, 1,
2791 new ArticleVersionComparator());
2792
2793 if (articles.isEmpty()) {
2794 throw new NoSuchArticleException(
2795 "No JournalArticle exists with the key {groupId=" + groupId +
2796 ", className=" + className + ", classPK =" + classPK + "}");
2797 }
2798
2799 return articles.get(0);
2800 }
2801
2802
2815 @Override
2816 public JournalArticle getLatestArticleByUrlTitle(
2817 long groupId, String urlTitle, int status)
2818 throws PortalException {
2819
2820 List<JournalArticle> articles = null;
2821
2822 OrderByComparator<JournalArticle> orderByComparator =
2823 new ArticleVersionComparator();
2824
2825 if (status == WorkflowConstants.STATUS_ANY) {
2826 articles = journalArticlePersistence.findByG_UT(
2827 groupId, urlTitle, 0, 1, orderByComparator);
2828 }
2829 else {
2830 articles = journalArticlePersistence.findByG_UT_ST(
2831 groupId, urlTitle, status, 0, 1, orderByComparator);
2832 }
2833
2834 if (articles.isEmpty()) {
2835 throw new NoSuchArticleException(
2836 "No JournalArticle exists with the key {groupId=" + groupId +
2837 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2838 }
2839
2840 return articles.get(0);
2841 }
2842
2843
2853 @Override
2854 public double getLatestVersion(long groupId, String articleId)
2855 throws PortalException {
2856
2857 JournalArticle article = getLatestArticle(groupId, articleId);
2858
2859 return article.getVersion();
2860 }
2861
2862
2875 @Override
2876 public double getLatestVersion(long groupId, String articleId, int status)
2877 throws PortalException {
2878
2879 JournalArticle article = getLatestArticle(groupId, articleId, status);
2880
2881 return article.getVersion();
2882 }
2883
2884
2891 @Override
2892 public int getNotInTrashArticlesCount(long groupId, long folderId) {
2893 QueryDefinition<JournalArticle> queryDefinition =
2894 new QueryDefinition<JournalArticle>(WorkflowConstants.STATUS_ANY);
2895
2896 List<Long> folderIds = new ArrayList<Long>();
2897
2898 folderIds.add(folderId);
2899
2900 return journalArticleFinder.countByG_F(
2901 groupId, folderIds, queryDefinition);
2902 }
2903
2904
2913 @Override
2914 public JournalArticle getOldestArticle(long groupId, String articleId)
2915 throws PortalException {
2916
2917 return getOldestArticle(
2918 groupId, articleId, WorkflowConstants.STATUS_ANY);
2919 }
2920
2921
2934 @Override
2935 public JournalArticle getOldestArticle(
2936 long groupId, String articleId, int status)
2937 throws PortalException {
2938
2939 return getFirstArticle(
2940 groupId, articleId, status, new ArticleVersionComparator(false));
2941 }
2942
2943
2953 @Override
2954 public JournalArticle getPreviousApprovedArticle(JournalArticle article) {
2955 List<JournalArticle> approvedArticles =
2956 journalArticlePersistence.findByG_A_ST(
2957 article.getGroupId(), article.getArticleId(),
2958 WorkflowConstants.STATUS_APPROVED, 0, 2);
2959
2960 if (approvedArticles.isEmpty() ||
2961 ((approvedArticles.size() == 1) &&
2962 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
2963
2964 return article;
2965 }
2966
2967 JournalArticle previousApprovedArticle = approvedArticles.get(0);
2968
2969 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
2970 previousApprovedArticle = approvedArticles.get(1);
2971 }
2972
2973 return previousApprovedArticle;
2974 }
2975
2976
2985 @Override
2986 public List<JournalArticle> getStructureArticles(
2987 long groupId, String ddmStructureKey) {
2988
2989 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
2990 }
2991
2992
3016 @Override
3017 public List<JournalArticle> getStructureArticles(
3018 long groupId, String ddmStructureKey, int start, int end,
3019 OrderByComparator<JournalArticle> obc) {
3020
3021 return journalArticlePersistence.findByG_S(
3022 groupId, ddmStructureKey, start, end, obc);
3023 }
3024
3025
3032 @Override
3033 public List<JournalArticle> getStructureArticles(
3034 String[] ddmStructureKeys) {
3035
3036 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
3037 }
3038
3039
3048 @Override
3049 public int getStructureArticlesCount(long groupId, String ddmStructureKey) {
3050 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
3051 }
3052
3053
3061 @Override
3062 public List<JournalArticle> getTemplateArticles(
3063 long groupId, String ddmTemplateKey) {
3064
3065 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3066 }
3067
3068
3092 @Override
3093 public List<JournalArticle> getTemplateArticles(
3094 long groupId, String ddmTemplateKey, int start, int end,
3095 OrderByComparator<JournalArticle> obc) {
3096
3097 return journalArticlePersistence.findByG_T(
3098 groupId, ddmTemplateKey, start, end, obc);
3099 }
3100
3101
3110 @Override
3111 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey) {
3112 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3113 }
3114
3115
3124 @Override
3125 public String getUniqueUrlTitle(
3126 long groupId, String articleId, String urlTitle)
3127 throws PortalException {
3128
3129 for (int i = 1;; i++) {
3130 JournalArticle article = null;
3131
3132 try {
3133 article = getArticleByUrlTitle(groupId, urlTitle);
3134 }
3135 catch (NoSuchArticleException nsae) {
3136 }
3137
3138 if ((article == null) || articleId.equals(article.getArticleId())) {
3139 break;
3140 }
3141 else {
3142 String suffix = StringPool.DASH + i;
3143
3144 String prefix = urlTitle;
3145
3146 if (urlTitle.length() > suffix.length()) {
3147 prefix = urlTitle.substring(
3148 0, urlTitle.length() - suffix.length());
3149 }
3150
3151 urlTitle = prefix + suffix;
3152 }
3153 }
3154
3155 return urlTitle;
3156 }
3157
3158
3166 @Override
3167 public boolean hasArticle(long groupId, String articleId) {
3168 try {
3169 getArticle(groupId, articleId);
3170
3171 return true;
3172 }
3173 catch (PortalException pe) {
3174 return false;
3175 }
3176 }
3177
3178
3190 @Override
3191 public boolean isLatestVersion(
3192 long groupId, String articleId, double version)
3193 throws PortalException {
3194
3195 if (getLatestVersion(groupId, articleId) == version) {
3196 return true;
3197 }
3198 else {
3199 return false;
3200 }
3201 }
3202
3203
3218 @Override
3219 public boolean isLatestVersion(
3220 long groupId, String articleId, double version, int status)
3221 throws PortalException {
3222
3223 if (getLatestVersion(groupId, articleId, status) == version) {
3224 return true;
3225 }
3226 else {
3227 return false;
3228 }
3229 }
3230
3231 @Override
3232 public boolean isRenderable(
3233 JournalArticle article, PortletRequestModel portletRequestModel,
3234 ThemeDisplay themeDisplay) {
3235
3236 try {
3237 getArticleDisplay(
3238 article, null, Constants.VIEW, article.getDefaultLanguageId(),
3239 0, portletRequestModel, themeDisplay, true);
3240 }
3241 catch (Exception e) {
3242 return false;
3243 }
3244
3245 return true;
3246 }
3247
3248
3260 @Indexable(type = IndexableType.REINDEX)
3261 @Override
3262 public JournalArticle moveArticle(
3263 long groupId, String articleId, long newFolderId)
3264 throws PortalException {
3265
3266 JournalArticle latestArticle = getLatestArticle(groupId, articleId);
3267
3268 validateDDMStructureId(
3269 groupId, newFolderId, latestArticle.getStructureId());
3270
3271 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3272 groupId, articleId);
3273
3274 for (JournalArticle article : articles) {
3275 article.setFolderId(newFolderId);
3276 article.setTreePath(article.buildTreePath());
3277
3278 journalArticlePersistence.update(article);
3279 }
3280
3281 return getArticle(groupId, articleId);
3282 }
3283
3284
3306 @Indexable(type = IndexableType.REINDEX)
3307 @Override
3308 public JournalArticle moveArticleFromTrash(
3309 long userId, long groupId, JournalArticle article, long newFolderId,
3310 ServiceContext serviceContext)
3311 throws PortalException {
3312
3313 if (article.isInTrashExplicitly()) {
3314 restoreArticleFromTrash(userId, article);
3315 }
3316 else {
3317
3318
3319
3320 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
3321 JournalArticle.class.getName(), article.getResourcePrimKey());
3322
3323 int status = WorkflowConstants.STATUS_APPROVED;
3324
3325 if (trashVersion != null) {
3326 status = trashVersion.getStatus();
3327 }
3328
3329 updateStatus(
3330 userId, article, status, null, serviceContext,
3331 new HashMap<String, Serializable>());
3332
3333
3334
3335 if (trashVersion != null) {
3336 trashVersionLocalService.deleteTrashVersion(trashVersion);
3337 }
3338 }
3339
3340 return moveArticle(groupId, article.getArticleId(), newFolderId);
3341 }
3342
3343
3355 @Indexable(type = IndexableType.REINDEX)
3356 @Override
3357 public JournalArticle moveArticleToTrash(
3358 long userId, JournalArticle article)
3359 throws PortalException {
3360
3361
3362
3363 int oldStatus = article.getStatus();
3364
3365 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3366 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3367
3368 journalArticlePersistence.update(article);
3369 }
3370
3371 List<JournalArticle> articleVersions =
3372 journalArticlePersistence.findByG_A(
3373 article.getGroupId(), article.getArticleId());
3374
3375 articleVersions = ListUtil.sort(
3376 articleVersions, new ArticleVersionComparator());
3377
3378 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
3379 new ArrayList<ObjectValuePair<Long, Integer>>();
3380
3381 if ((articleVersions != null) && !articleVersions.isEmpty()) {
3382 articleVersionStatusOVPs = getArticleVersionStatuses(
3383 articleVersions);
3384 }
3385
3386 article = updateStatus(
3387 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3388 new HashMap<String, Serializable>(), new ServiceContext());
3389
3390
3391
3392 JournalArticleResource articleResource =
3393 journalArticleResourceLocalService.getArticleResource(
3394 article.getResourcePrimKey());
3395
3396 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
3397
3398 typeSettingsProperties.put("title", article.getArticleId());
3399
3400 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
3401 userId, article.getGroupId(), JournalArticle.class.getName(),
3402 article.getResourcePrimKey(), articleResource.getUuid(), null,
3403 oldStatus, articleVersionStatusOVPs, typeSettingsProperties);
3404
3405 String trashArticleId = TrashUtil.getTrashTitle(
3406 trashEntry.getEntryId());
3407
3408 for (JournalArticle articleVersion : articleVersions) {
3409 articleVersion.setArticleId(trashArticleId);
3410 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
3411
3412 journalArticlePersistence.update(articleVersion);
3413 }
3414
3415 articleResource.setArticleId(trashArticleId);
3416
3417 journalArticleResourcePersistence.update(articleResource);
3418
3419 article.setArticleId(trashArticleId);
3420
3421 article = journalArticlePersistence.update(article);
3422
3423
3424
3425 assetEntryLocalService.updateVisible(
3426 JournalArticle.class.getName(), article.getResourcePrimKey(),
3427 false);
3428
3429
3430
3431 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3432
3433 extraDataJSONObject.put("title", article.getTitle());
3434
3435 socialActivityLocalService.addActivity(
3436 userId, article.getGroupId(), JournalArticle.class.getName(),
3437 article.getResourcePrimKey(),
3438 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3439 extraDataJSONObject.toString(), 0);
3440
3441 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3442 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3443 article.getCompanyId(), article.getGroupId(),
3444 JournalArticle.class.getName(), article.getId());
3445 }
3446
3447 return article;
3448 }
3449
3450
3463 @Override
3464 public JournalArticle moveArticleToTrash(
3465 long userId, long groupId, String articleId)
3466 throws PortalException {
3467
3468 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3469 groupId, articleId, 0, 1, new ArticleVersionComparator());
3470
3471 if (!articles.isEmpty()) {
3472 return journalArticleLocalService.moveArticleToTrash(
3473 userId, articles.get(0));
3474 }
3475
3476 return null;
3477 }
3478
3479
3498 @Override
3499 public void rebuildTree(long companyId) throws PortalException {
3500 journalFolderLocalService.rebuildTree(companyId);
3501 }
3502
3503
3515 @Indexable(type = IndexableType.REINDEX)
3516 @Override
3517 public JournalArticle removeArticleLocale(
3518 long groupId, String articleId, double version, String languageId)
3519 throws PortalException {
3520
3521 JournalArticle article = journalArticlePersistence.findByG_A_V(
3522 groupId, articleId, version);
3523
3524 String title = article.getTitle();
3525
3526 title = LocalizationUtil.removeLocalization(
3527 title, "static-content", languageId, true);
3528
3529 article.setTitle(title);
3530
3531 String description = article.getDescription();
3532
3533 description = LocalizationUtil.removeLocalization(
3534 description, "static-content", languageId, true);
3535
3536 article.setDescription(description);
3537
3538 String content = article.getContent();
3539
3540 Document document = article.getDocument();
3541
3542 if (document != null) {
3543 content = JournalUtil.removeArticleLocale(
3544 document, content, languageId);
3545
3546 article.setContent(content);
3547 }
3548
3549 journalArticlePersistence.update(article);
3550
3551 return article;
3552 }
3553
3554
3566 @Indexable(type = IndexableType.REINDEX)
3567 @Override
3568 public JournalArticle restoreArticleFromTrash(
3569 long userId, JournalArticle article)
3570 throws PortalException {
3571
3572
3573
3574 String trashArticleId = TrashUtil.getOriginalTitle(
3575 article.getArticleId());
3576
3577 List<JournalArticle> articleVersions =
3578 journalArticlePersistence.findByG_A(
3579 article.getGroupId(), article.getArticleId());
3580
3581 for (JournalArticle articleVersion : articleVersions) {
3582 articleVersion.setArticleId(trashArticleId);
3583
3584 journalArticlePersistence.update(articleVersion);
3585 }
3586
3587 article.setArticleId(trashArticleId);
3588
3589 journalArticlePersistence.update(article);
3590
3591 JournalArticleResource articleResource =
3592 journalArticleResourcePersistence.fetchByPrimaryKey(
3593 article.getResourcePrimKey());
3594
3595 articleResource.setArticleId(trashArticleId);
3596
3597 journalArticleResourcePersistence.update(articleResource);
3598
3599 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3600 JournalArticle.class.getName(), article.getResourcePrimKey());
3601
3602 ServiceContext serviceContext = new ServiceContext();
3603
3604 serviceContext.setScopeGroupId(article.getGroupId());
3605
3606 updateStatus(
3607 userId, article, trashEntry.getStatus(), null, serviceContext,
3608 new HashMap<String, Serializable>());
3609
3610
3611
3612 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3613 trashEntry.getEntryId());
3614
3615 for (TrashVersion trashVersion : trashVersions) {
3616 JournalArticle trashArticleVersion =
3617 journalArticlePersistence.findByPrimaryKey(
3618 trashVersion.getClassPK());
3619
3620 trashArticleVersion.setStatus(trashVersion.getStatus());
3621
3622 journalArticlePersistence.update(trashArticleVersion);
3623 }
3624
3625 trashEntryLocalService.deleteEntry(
3626 JournalArticle.class.getName(), article.getResourcePrimKey());
3627
3628
3629
3630 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3631
3632 extraDataJSONObject.put("title", article.getTitle());
3633
3634 socialActivityLocalService.addActivity(
3635 userId, article.getGroupId(), JournalArticle.class.getName(),
3636 article.getResourcePrimKey(),
3637 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3638 extraDataJSONObject.toString(), 0);
3639
3640 return article;
3641 }
3642
3643
3670 @Override
3671 public List<JournalArticle> search(
3672 long groupId, List<Long> folderIds, int status, int start, int end) {
3673
3674 QueryDefinition<JournalArticle> queryDefinition =
3675 new QueryDefinition<JournalArticle>(status, start, end, null);
3676
3677 return journalArticleFinder.findByG_F(
3678 groupId, folderIds, queryDefinition);
3679 }
3680
3681
3707 @Override
3708 public List<JournalArticle> search(
3709 long groupId, long folderId, int status, int start, int end) {
3710
3711 List<Long> folderIds = new ArrayList<Long>();
3712
3713 folderIds.add(folderId);
3714
3715 return search(groupId, folderIds, status, start, end);
3716 }
3717
3718
3777 @Override
3778 public List<JournalArticle> search(
3779 long companyId, long groupId, List<Long> folderIds, long classNameId,
3780 String keywords, Double version, String type, String ddmStructureKey,
3781 String ddmTemplateKey, Date displayDateGT, Date displayDateLT,
3782 int status, Date reviewDate, int start, int end,
3783 OrderByComparator<JournalArticle> obc) {
3784
3785 return journalArticleFinder.findByKeywords(
3786 companyId, groupId, folderIds, classNameId, keywords, version, type,
3787 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3788 status, reviewDate, start, end, obc);
3789 }
3790
3791
3857 @Override
3858 public List<JournalArticle> search(
3859 long companyId, long groupId, List<Long> folderIds, long classNameId,
3860 String articleId, Double version, String title, String description,
3861 String content, String type, String ddmStructureKey,
3862 String ddmTemplateKey, Date displayDateGT, Date displayDateLT,
3863 int status, Date reviewDate, boolean andOperator, int start, int end,
3864 OrderByComparator<JournalArticle> obc) {
3865
3866 QueryDefinition<JournalArticle> queryDefinition =
3867 new QueryDefinition<JournalArticle>(status, start, end, obc);
3868
3869 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3870 companyId, groupId, folderIds, classNameId, articleId, version,
3871 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3872 displayDateGT, displayDateLT, reviewDate, andOperator,
3873 queryDefinition);
3874 }
3875
3876
3941 @Override
3942 public List<JournalArticle> search(
3943 long companyId, long groupId, List<Long> folderIds, long classNameId,
3944 String articleId, Double version, String title, String description,
3945 String content, String type, String[] ddmStructureKeys,
3946 String[] ddmTemplateKeys, Date displayDateGT, Date displayDateLT,
3947 int status, Date reviewDate, boolean andOperator, int start, int end,
3948 OrderByComparator<JournalArticle> obc) {
3949
3950 QueryDefinition<JournalArticle> queryDefinition =
3951 new QueryDefinition<JournalArticle>(status, start, end, obc);
3952
3953 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3954 companyId, groupId, folderIds, classNameId, articleId, version,
3955 title, description, content, type, ddmStructureKeys,
3956 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3957 andOperator, queryDefinition);
3958 }
3959
3960
4004 @Override
4005 public Hits search(
4006 long companyId, long groupId, List<Long> folderIds, long classNameId,
4007 String ddmStructureKey, String ddmTemplateKey, String keywords,
4008 LinkedHashMap<String, Object> params, int start, int end, Sort sort) {
4009
4010 String articleId = null;
4011 String title = null;
4012 String description = null;
4013 String content = null;
4014 boolean andOperator = false;
4015
4016 if (Validator.isNotNull(keywords)) {
4017 articleId = keywords;
4018 title = keywords;
4019 description = keywords;
4020 content = keywords;
4021 }
4022 else {
4023 andOperator = true;
4024 }
4025
4026 if (params != null) {
4027 params.put("keywords", keywords);
4028 }
4029
4030 return search(
4031 companyId, groupId, folderIds, classNameId, articleId, title,
4032 description, content, null, WorkflowConstants.STATUS_ANY,
4033 ddmStructureKey, ddmTemplateKey, params, andOperator, start, end,
4034 sort);
4035 }
4036
4037
4095 @Override
4096 public Hits search(
4097 long companyId, long groupId, List<Long> folderIds, long classNameId,
4098 String articleId, String title, String description, String content,
4099 String type, int status, String ddmStructureKey, String ddmTemplateKey,
4100 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4101 int end, Sort sort) {
4102
4103 try {
4104 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4105 JournalArticle.class);
4106
4107 SearchContext searchContext = buildSearchContext(
4108 companyId, groupId, folderIds, classNameId, articleId, title,
4109 description, content, type, status, ddmStructureKey,
4110 ddmTemplateKey, params, andSearch, start, end, sort);
4111
4112 return indexer.search(searchContext);
4113 }
4114 catch (Exception e) {
4115 throw new SystemException(e);
4116 }
4117 }
4118
4119
4124 @Deprecated
4125 @Override
4126 public Hits search(
4127 long companyId, long groupId, List<Long> folderIds, long classNameId,
4128 String articleId, String title, String description, String content,
4129 String type, String statusString, String ddmStructureKey,
4130 String ddmTemplateKey, LinkedHashMap<String, Object> params,
4131 boolean andSearch, int start, int end, Sort sort) {
4132
4133 int status = GetterUtil.getInteger(statusString);
4134
4135 return search(
4136 companyId, groupId, folderIds, classNameId, articleId, title,
4137 description, content, type, status, ddmStructureKey, ddmTemplateKey,
4138 params, andSearch, start, end, sort);
4139 }
4140
4141
4170 @Override
4171 public Hits search(
4172 long groupId, long userId, long creatorUserId, int status,
4173 int start, int end)
4174 throws PortalException {
4175
4176 Indexer indexer = IndexerRegistryUtil.getIndexer(
4177 JournalArticle.class.getName());
4178
4179 SearchContext searchContext = buildSearchContext(
4180 groupId, userId, creatorUserId, status, start, end);
4181
4182 return indexer.search(searchContext);
4183 }
4184
4185
4197 @Override
4198 public int searchCount(long groupId, List<Long> folderIds, int status) {
4199 QueryDefinition<JournalArticle> queryDefinition =
4200 new QueryDefinition<JournalArticle>(status);
4201
4202 return journalArticleFinder.countByG_F(
4203 groupId, folderIds, queryDefinition);
4204 }
4205
4206
4217 @Override
4218 public int searchCount(long groupId, long folderId, int status) {
4219 List<Long> folderIds = new ArrayList<Long>();
4220
4221 folderIds.add(folderId);
4222
4223 return searchCount(groupId, folderIds, status);
4224 }
4225
4226
4267 @Override
4268 public int searchCount(
4269 long companyId, long groupId, List<Long> folderIds, long classNameId,
4270 String keywords, Double version, String type, String ddmStructureKey,
4271 String ddmTemplateKey, Date displayDateGT, Date displayDateLT,
4272 int status, Date reviewDate) {
4273
4274 return journalArticleFinder.countByKeywords(
4275 companyId, groupId, folderIds, classNameId, keywords, version, type,
4276 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4277 status, reviewDate);
4278 }
4279
4280
4327 @Override
4328 public int searchCount(
4329 long companyId, long groupId, List<Long> folderIds, long classNameId,
4330 String articleId, Double version, String title, String description,
4331 String content, String type, String ddmStructureKey,
4332 String ddmTemplateKey, Date displayDateGT, Date displayDateLT,
4333 int status, Date reviewDate, boolean andOperator) {
4334
4335 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4336 companyId, groupId, folderIds, classNameId, articleId, version,
4337 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4338 displayDateGT, displayDateLT, reviewDate, andOperator,
4339 new QueryDefinition<JournalArticle>(status));
4340 }
4341
4342
4391 @Override
4392 public int searchCount(
4393 long companyId, long groupId, List<Long> folderIds, long classNameId,
4394 String articleId, Double version, String title, String description,
4395 String content, String type, String[] ddmStructureKeys,
4396 String[] ddmTemplateKeys, Date displayDateGT, Date displayDateLT,
4397 int status, Date reviewDate, boolean andOperator) {
4398
4399 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4400 companyId, groupId, folderIds, classNameId, articleId, version,
4401 title, description, content, type, ddmStructureKeys,
4402 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4403 andOperator, new QueryDefinition<JournalArticle>(status));
4404 }
4405
4406
4458 @Override
4459 public BaseModelSearchResult<JournalArticle> searchJournalArticles(
4460 long companyId, long groupId, List<Long> folderIds,
4461 long classNameId, String ddmStructureKey, String ddmTemplateKey,
4462 String keywords, LinkedHashMap<String, Object> params, int start,
4463 int end, Sort sort)
4464 throws PortalException {
4465
4466 String articleId = null;
4467 String title = null;
4468 String description = null;
4469 String content = null;
4470 boolean andOperator = false;
4471
4472 if (Validator.isNotNull(keywords)) {
4473 articleId = keywords;
4474 title = keywords;
4475 description = keywords;
4476 content = keywords;
4477 }
4478 else {
4479 andOperator = true;
4480 }
4481
4482 if (params != null) {
4483 params.put("keywords", keywords);
4484 }
4485
4486 return searchJournalArticles(
4487 companyId, groupId, folderIds, classNameId, articleId, title,
4488 description, content, null, WorkflowConstants.STATUS_ANY,
4489 ddmStructureKey, ddmTemplateKey, params, andOperator, start, end,
4490 sort);
4491 }
4492
4493
4558 @Override
4559 public BaseModelSearchResult<JournalArticle> searchJournalArticles(
4560 long companyId, long groupId, List<Long> folderIds,
4561 long classNameId, String articleId, String title,
4562 String description, String content, String type, int status,
4563 String ddmStructureKey, String ddmTemplateKey,
4564 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4565 int end, Sort sort)
4566 throws PortalException {
4567
4568 SearchContext searchContext = buildSearchContext(
4569 companyId, groupId, folderIds, classNameId, articleId, title,
4570 description, content, type, status, ddmStructureKey, ddmTemplateKey,
4571 params, andSearch, start, end, sort);
4572
4573 return searchJournalArticles(searchContext);
4574 }
4575
4576
4615 @Override
4616 public BaseModelSearchResult<JournalArticle> searchJournalArticles(
4617 long groupId, long userId, long creatorUserId, int status,
4618 int start, int end)
4619 throws PortalException {
4620
4621 SearchContext searchContext = buildSearchContext(
4622 groupId, userId, creatorUserId, status, start, end);
4623
4624 return searchJournalArticles(searchContext);
4625 }
4626
4627 @Override
4628 public void setTreePaths(
4629 final long folderId, final String treePath, final boolean reindex)
4630 throws PortalException {
4631
4632 ActionableDynamicQuery actionableDynamicQuery =
4633 getActionableDynamicQuery();
4634
4635 actionableDynamicQuery.setAddCriteriaMethod(
4636 new ActionableDynamicQuery.AddCriteriaMethod() {
4637
4638 @Override
4639 public void addCriteria(DynamicQuery dynamicQuery) {
4640 Property folderIdProperty = PropertyFactoryUtil.forName(
4641 "folderId");
4642
4643 dynamicQuery.add(folderIdProperty.eq(folderId));
4644
4645 Property treePathProperty = PropertyFactoryUtil.forName(
4646 "treePath");
4647
4648 dynamicQuery.add(treePathProperty.ne(treePath));
4649 }
4650
4651 });
4652
4653 final Indexer indexer = IndexerRegistryUtil.getIndexer(
4654 JournalArticle.class.getName());
4655
4656 actionableDynamicQuery.setPerformActionMethod(
4657 new ActionableDynamicQuery.PerformActionMethod() {
4658
4659 @Override
4660 public void performAction(Object object)
4661 throws PortalException {
4662
4663 JournalArticle article = (JournalArticle)object;
4664
4665 article.setTreePath(treePath);
4666
4667 updateJournalArticle(article);
4668
4669 if (!reindex) {
4670 return;
4671 }
4672
4673 indexer.reindex(article);
4674 }
4675
4676 });
4677
4678 actionableDynamicQuery.performActions();
4679 }
4680
4681
4690 @Override
4691 public void subscribeStructure(
4692 long groupId, long userId, long ddmStructureId)
4693 throws PortalException {
4694
4695 subscriptionLocalService.addSubscription(
4696 userId, groupId, DDMStructure.class.getName(), ddmStructureId);
4697 }
4698
4699
4709 @Override
4710 public void unsubscribeStructure(
4711 long groupId, long userId, long ddmStructureId)
4712 throws PortalException {
4713
4714 subscriptionLocalService.deleteSubscription(
4715 userId, DDMStructure.class.getName(), ddmStructureId);
4716 }
4717
4718
4751 @Override
4752 public JournalArticle updateArticle(
4753 long userId, long groupId, long folderId, String articleId,
4754 double version, Map<Locale, String> titleMap,
4755 Map<Locale, String> descriptionMap, String content,
4756 String layoutUuid, ServiceContext serviceContext)
4757 throws PortalException {
4758
4759 User user = userPersistence.findByPrimaryKey(userId);
4760
4761 JournalArticle article = journalArticlePersistence.findByG_A_V(
4762 groupId, articleId, version);
4763
4764 Date displayDate = article.getDisplayDate();
4765
4766 int displayDateMonth = 0;
4767 int displayDateDay = 0;
4768 int displayDateYear = 0;
4769 int displayDateHour = 0;
4770 int displayDateMinute = 0;
4771
4772 if (displayDate != null) {
4773 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4774 user.getTimeZone());
4775
4776 displayCal.setTime(displayDate);
4777
4778 displayDateMonth = displayCal.get(Calendar.MONTH);
4779 displayDateDay = displayCal.get(Calendar.DATE);
4780 displayDateYear = displayCal.get(Calendar.YEAR);
4781 displayDateHour = displayCal.get(Calendar.HOUR);
4782 displayDateMinute = displayCal.get(Calendar.MINUTE);
4783
4784 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4785 displayDateHour += 12;
4786 }
4787 }
4788
4789 Date expirationDate = article.getExpirationDate();
4790
4791 int expirationDateMonth = 0;
4792 int expirationDateDay = 0;
4793 int expirationDateYear = 0;
4794 int expirationDateHour = 0;
4795 int expirationDateMinute = 0;
4796 boolean neverExpire = true;
4797
4798 if (expirationDate != null) {
4799 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4800 user.getTimeZone());
4801
4802 expirationCal.setTime(expirationDate);
4803
4804 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4805 expirationDateDay = expirationCal.get(Calendar.DATE);
4806 expirationDateYear = expirationCal.get(Calendar.YEAR);
4807 expirationDateHour = expirationCal.get(Calendar.HOUR);
4808 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4809 neverExpire = false;
4810
4811 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4812 expirationDateHour += 12;
4813 }
4814 }
4815
4816 Date reviewDate = article.getReviewDate();
4817
4818 int reviewDateMonth = 0;
4819 int reviewDateDay = 0;
4820 int reviewDateYear = 0;
4821 int reviewDateHour = 0;
4822 int reviewDateMinute = 0;
4823 boolean neverReview = true;
4824
4825 if (reviewDate != null) {
4826 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4827 user.getTimeZone());
4828
4829 reviewCal.setTime(reviewDate);
4830
4831 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4832 reviewDateDay = reviewCal.get(Calendar.DATE);
4833 reviewDateYear = reviewCal.get(Calendar.YEAR);
4834 reviewDateHour = reviewCal.get(Calendar.HOUR);
4835 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4836 neverReview = false;
4837
4838 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4839 reviewDateHour += 12;
4840 }
4841 }
4842
4843 return journalArticleLocalService.updateArticle(
4844 userId, groupId, folderId, articleId, version, titleMap,
4845 descriptionMap, content, article.getType(),
4846 article.getStructureId(), article.getTemplateId(), layoutUuid,
4847 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4848 displayDateMinute, expirationDateMonth, expirationDateDay,
4849 expirationDateYear, expirationDateHour, expirationDateMinute,
4850 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4851 reviewDateHour, reviewDateMinute, neverReview,
4852 article.getIndexable(), article.isSmallImage(),
4853 article.getSmallImageURL(), null, null, null, serviceContext);
4854 }
4855
4856
4940 @Indexable(type = IndexableType.REINDEX)
4941 @Override
4942 public JournalArticle updateArticle(
4943 long userId, long groupId, long folderId, String articleId,
4944 double version, Map<Locale, String> titleMap,
4945 Map<Locale, String> descriptionMap, String content, String type,
4946 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4947 int displayDateMonth, int displayDateDay, int displayDateYear,
4948 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4949 int expirationDateDay, int expirationDateYear,
4950 int expirationDateHour, int expirationDateMinute,
4951 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4952 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4953 boolean neverReview, boolean indexable, boolean smallImage,
4954 String smallImageURL, File smallImageFile,
4955 Map<String, byte[]> images, String articleURL,
4956 ServiceContext serviceContext)
4957 throws PortalException {
4958
4959
4960
4961 User user = userPersistence.findByPrimaryKey(userId);
4962 articleId = StringUtil.toUpperCase(articleId.trim());
4963
4964 byte[] smallImageBytes = null;
4965
4966 try {
4967 smallImageBytes = FileUtil.getBytes(smallImageFile);
4968 }
4969 catch (IOException ioe) {
4970 }
4971
4972 JournalArticle latestArticle = getLatestArticle(
4973 groupId, articleId, WorkflowConstants.STATUS_ANY);
4974
4975 JournalArticle article = latestArticle;
4976
4977 boolean imported = ExportImportThreadLocal.isImportInProcess();
4978
4979 double latestVersion = latestArticle.getVersion();
4980
4981 boolean addNewVersion = false;
4982
4983 if (imported) {
4984 article = getArticle(groupId, articleId, version);
4985 }
4986 else {
4987 if ((version > 0) && (version != latestVersion)) {
4988 throw new ArticleVersionException();
4989 }
4990
4991 serviceContext.validateModifiedDate(
4992 latestArticle, ArticleVersionException.class);
4993
4994 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4995 latestArticle.isScheduled()) {
4996
4997 addNewVersion = true;
4998
4999 version = MathUtil.format(latestVersion + 0.1, 1, 1);
5000 }
5001 }
5002
5003 Date displayDate = null;
5004 Date expirationDate = null;
5005 Date reviewDate = null;
5006
5007 if (article.getClassNameId() ==
5008 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5009
5010 displayDate = PortalUtil.getDate(
5011 displayDateMonth, displayDateDay, displayDateYear,
5012 displayDateHour, displayDateMinute, user.getTimeZone(),
5013 ArticleDisplayDateException.class);
5014
5015 if (!neverExpire) {
5016 expirationDate = PortalUtil.getDate(
5017 expirationDateMonth, expirationDateDay, expirationDateYear,
5018 expirationDateHour, expirationDateMinute,
5019 user.getTimeZone(), ArticleExpirationDateException.class);
5020 }
5021
5022 if (!neverReview) {
5023 reviewDate = PortalUtil.getDate(
5024 reviewDateMonth, reviewDateDay, reviewDateYear,
5025 reviewDateHour, reviewDateMinute, user.getTimeZone(),
5026 ArticleReviewDateException.class);
5027 }
5028 }
5029
5030 Date now = new Date();
5031
5032 boolean expired = false;
5033
5034 if ((expirationDate != null) && expirationDate.before(now)) {
5035 expired = true;
5036 }
5037
5038 validate(
5039 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
5040 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
5041 expirationDate, smallImage, smallImageURL, smallImageFile,
5042 smallImageBytes, serviceContext);
5043
5044 if (addNewVersion) {
5045 long id = counterLocalService.increment();
5046
5047 article = journalArticlePersistence.create(id);
5048
5049 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
5050 article.setGroupId(latestArticle.getGroupId());
5051 article.setCompanyId(latestArticle.getCompanyId());
5052 article.setCreateDate(latestArticle.getCreateDate());
5053 article.setClassNameId(latestArticle.getClassNameId());
5054 article.setClassPK(latestArticle.getClassPK());
5055 article.setArticleId(articleId);
5056 article.setVersion(version);
5057 article.setSmallImageId(latestArticle.getSmallImageId());
5058 }
5059
5060 Locale locale = getArticleDefaultLocale(content, serviceContext);
5061
5062 String title = titleMap.get(locale);
5063
5064 content = format(
5065 user, groupId, articleId, article.getVersion(), addNewVersion,
5066 content, ddmStructureKey, images);
5067
5068 article.setUserId(user.getUserId());
5069 article.setUserName(user.getFullName());
5070 article.setModifiedDate(serviceContext.getModifiedDate(now));
5071 article.setFolderId(folderId);
5072 article.setTreePath(article.buildTreePath());
5073 article.setTitleMap(titleMap, locale);
5074 article.setUrlTitle(
5075 getUniqueUrlTitle(
5076 article.getId(), article.getArticleId(), title,
5077 latestArticle.getUrlTitle(), serviceContext));
5078 article.setDescriptionMap(descriptionMap, locale);
5079 article.setContent(content);
5080 article.setType(type);
5081 article.setStructureId(ddmStructureKey);
5082 article.setTemplateId(ddmTemplateKey);
5083 article.setLayoutUuid(layoutUuid);
5084 article.setDisplayDate(displayDate);
5085 article.setExpirationDate(expirationDate);
5086 article.setReviewDate(reviewDate);
5087 article.setIndexable(indexable);
5088 article.setSmallImage(smallImage);
5089
5090 if (smallImage) {
5091 if ((smallImageFile != null) && (smallImageBytes != null)) {
5092 article.setSmallImageId(counterLocalService.increment());
5093 }
5094 }
5095 else {
5096 article.setSmallImageId(0);
5097 }
5098
5099 article.setSmallImageURL(smallImageURL);
5100
5101 if (latestArticle.isPending()) {
5102 article.setStatus(latestArticle.getStatus());
5103 }
5104 else if (!expired) {
5105 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5106 }
5107 else {
5108 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5109 }
5110
5111 article.setExpandoBridgeAttributes(serviceContext);
5112
5113 journalArticlePersistence.update(article);
5114
5115
5116
5117 updateAsset(
5118 userId, article, serviceContext.getAssetCategoryIds(),
5119 serviceContext.getAssetTagNames(),
5120 serviceContext.getAssetLinkEntryIds());
5121
5122
5123
5124 if (classNameLocalService.getClassNameId(DDMStructure.class) ==
5125 article.getClassNameId()) {
5126
5127 updateDDMStructurePredefinedValues(
5128 article.getClassPK(), content, serviceContext);
5129 }
5130
5131
5132
5133 saveImages(
5134 smallImage, article.getSmallImageId(), smallImageFile,
5135 smallImageBytes);
5136
5137
5138
5139 PortletPreferences preferences =
5140 ServiceContextUtil.getPortletPreferences(serviceContext);
5141
5142
5143
5144 if (expired && imported) {
5145 updateStatus(
5146 userId, article, article.getStatus(), articleURL,
5147 serviceContext, new HashMap<String, Serializable>());
5148 }
5149
5150 if (serviceContext.getWorkflowAction() ==
5151 WorkflowConstants.ACTION_PUBLISH) {
5152
5153 articleURL = buildArticleURL(
5154 articleURL, groupId, folderId, articleId);
5155
5156 serviceContext.setAttribute("articleURL", articleURL);
5157
5158 sendEmail(
5159 article, articleURL, preferences, "requested", serviceContext);
5160
5161 startWorkflowInstance(userId, article, serviceContext);
5162 }
5163
5164 return journalArticlePersistence.findByPrimaryKey(article.getId());
5165 }
5166
5167
5195 @Override
5196 public JournalArticle updateArticle(
5197 long userId, long groupId, long folderId, String articleId,
5198 double version, String content, ServiceContext serviceContext)
5199 throws PortalException {
5200
5201 JournalArticle article = journalArticlePersistence.findByG_A_V(
5202 groupId, articleId, version);
5203
5204 return journalArticleLocalService.updateArticle(
5205 userId, groupId, folderId, articleId, version,
5206 article.getTitleMap(), article.getDescriptionMap(), content,
5207 article.getLayoutUuid(), serviceContext);
5208 }
5209
5210
5215 @Deprecated
5216 @Override
5217 public JournalArticle updateArticleTranslation(
5218 long groupId, String articleId, double version, Locale locale,
5219 String title, String description, String content,
5220 Map<String, byte[]> images)
5221 throws PortalException {
5222
5223 return journalArticleLocalService.updateArticleTranslation(
5224 groupId, articleId, version, locale, title, description, content,
5225 images, null);
5226 }
5227
5228
5249 @Indexable(type = IndexableType.REINDEX)
5250 @Override
5251 public JournalArticle updateArticleTranslation(
5252 long groupId, String articleId, double version, Locale locale,
5253 String title, String description, String content,
5254 Map<String, byte[]> images, ServiceContext serviceContext)
5255 throws PortalException {
5256
5257 validateContent(content);
5258
5259 JournalArticle oldArticle = getLatestArticle(
5260 groupId, articleId, WorkflowConstants.STATUS_ANY);
5261
5262 double oldVersion = oldArticle.getVersion();
5263
5264 if ((version > 0) && (version != oldVersion)) {
5265 throw new ArticleVersionException();
5266 }
5267
5268 boolean incrementVersion = false;
5269
5270 if (oldArticle.isApproved() || oldArticle.isExpired()) {
5271 incrementVersion = true;
5272 }
5273
5274 if (serviceContext != null) {
5275 serviceContext.validateModifiedDate(
5276 oldArticle, ArticleVersionException.class);
5277 }
5278
5279 JournalArticle article = null;
5280
5281 User user = userPersistence.findByPrimaryKey(oldArticle.getUserId());
5282
5283 Locale defaultLocale = getArticleDefaultLocale(content, serviceContext);
5284
5285 if (incrementVersion) {
5286 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
5287
5288 long id = counterLocalService.increment();
5289
5290 article = journalArticlePersistence.create(id);
5291
5292 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
5293 article.setGroupId(oldArticle.getGroupId());
5294 article.setCompanyId(oldArticle.getCompanyId());
5295 article.setUserId(oldArticle.getUserId());
5296 article.setUserName(user.getFullName());
5297 article.setCreateDate(oldArticle.getCreateDate());
5298 article.setModifiedDate(new Date());
5299 article.setClassNameId(oldArticle.getClassNameId());
5300 article.setClassPK(oldArticle.getClassPK());
5301 article.setArticleId(articleId);
5302 article.setVersion(newVersion);
5303 article.setTitleMap(oldArticle.getTitleMap(), defaultLocale);
5304 article.setUrlTitle(
5305 getUniqueUrlTitle(
5306 id, articleId, title, oldArticle.getUrlTitle(),
5307 serviceContext));
5308 article.setDescriptionMap(oldArticle.getDescriptionMap());
5309 article.setType(oldArticle.getType());
5310 article.setStructureId(oldArticle.getStructureId());
5311 article.setTemplateId(oldArticle.getTemplateId());
5312 article.setLayoutUuid(oldArticle.getLayoutUuid());
5313 article.setDisplayDate(oldArticle.getDisplayDate());
5314 article.setExpirationDate(oldArticle.getExpirationDate());
5315 article.setReviewDate(oldArticle.getReviewDate());
5316 article.setIndexable(oldArticle.getIndexable());
5317 article.setSmallImage(oldArticle.getSmallImage());
5318 article.setSmallImageId(oldArticle.getSmallImageId());
5319
5320 if (article.getSmallImageId() == 0) {
5321 article.setSmallImageId(counterLocalService.increment());
5322 }
5323
5324 article.setSmallImageURL(oldArticle.getSmallImageURL());
5325
5326 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5327 article.setStatusDate(new Date());
5328 article.setExpandoBridgeAttributes(oldArticle);
5329 }
5330 else {
5331 article = oldArticle;
5332 }
5333
5334 Map<Locale, String> titleMap = article.getTitleMap();
5335
5336 titleMap.put(locale, title);
5337
5338 article.setTitleMap(titleMap, defaultLocale);
5339
5340 Map<Locale, String> descriptionMap = article.getDescriptionMap();
5341
5342 descriptionMap.put(locale, description);
5343
5344 article.setDescriptionMap(descriptionMap);
5345
5346 content = format(
5347 user, groupId, articleId, article.getVersion(),
5348 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
5349 images);
5350
5351 article.setContent(content);
5352
5353 journalArticlePersistence.update(article);
5354
5355 return article;
5356 }
5357
5358
5370 @Override
5371 public void updateAsset(
5372 long userId, JournalArticle article, long[] assetCategoryIds,
5373 String[] assetTagNames, long[] assetLinkEntryIds)
5374 throws PortalException {
5375
5376 boolean visible = article.isApproved();
5377
5378 if (article.getClassNameId() !=
5379 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5380
5381 visible = false;
5382 }
5383
5384 boolean addDraftAssetEntry = false;
5385
5386 if (!article.isApproved() &&
5387 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5388
5389 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5390 article.getGroupId(), article.getArticleId(),
5391 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5392
5393 if (approvedArticlesCount > 0) {
5394 addDraftAssetEntry = true;
5395 }
5396 }
5397
5398 AssetEntry assetEntry = null;
5399
5400 if (addDraftAssetEntry) {
5401 assetEntry = assetEntryLocalService.updateEntry(
5402 userId, article.getGroupId(), article.getCreateDate(),
5403 article.getModifiedDate(), JournalArticle.class.getName(),
5404 article.getPrimaryKey(), article.getUuid(),
5405 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5406 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5407 article.getDescription(), article.getDescription(), null,
5408 article.getLayoutUuid(), 0, 0, null, false);
5409 }
5410 else {
5411 JournalArticleResource journalArticleResource =
5412 journalArticleResourceLocalService.getArticleResource(
5413 article.getResourcePrimKey());
5414
5415 assetEntry = assetEntryLocalService.updateEntry(
5416 userId, article.getGroupId(), article.getCreateDate(),
5417 article.getModifiedDate(), JournalArticle.class.getName(),
5418 journalArticleResource.getResourcePrimKey(),
5419 journalArticleResource.getUuid(), getClassTypeId(article),
5420 assetCategoryIds, assetTagNames, visible, null, null, null,
5421 ContentTypes.TEXT_HTML, article.getTitle(),
5422 article.getDescription(), article.getDescription(), null,
5423 article.getLayoutUuid(), 0, 0, null, false);
5424 }
5425
5426 assetLinkLocalService.updateLinks(
5427 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5428 AssetLinkConstants.TYPE_RELATED);
5429 }
5430
5431
5445 @Indexable(type = IndexableType.REINDEX)
5446 @Override
5447 public JournalArticle updateContent(
5448 long groupId, String articleId, double version, String content)
5449 throws PortalException {
5450
5451 JournalArticle article = journalArticlePersistence.findByG_A_V(
5452 groupId, articleId, version);
5453
5454 article.setContent(content);
5455
5456 journalArticlePersistence.update(article);
5457
5458 return article;
5459 }
5460
5461
5483 @Indexable(type = IndexableType.REINDEX)
5484 @Override
5485 public JournalArticle updateStatus(
5486 long userId, JournalArticle article, int status, String articleURL,
5487 ServiceContext serviceContext,
5488 Map<String, Serializable> workflowContext)
5489 throws PortalException {
5490
5491
5492
5493 User user = userPersistence.findByPrimaryKey(userId);
5494 Date now = new Date();
5495
5496 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5497 (article.getClassNameId() ==
5498 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5499 (article.getDisplayDate() != null) &&
5500 now.before(article.getDisplayDate())) {
5501
5502 status = WorkflowConstants.STATUS_SCHEDULED;
5503 }
5504
5505 int oldStatus = article.getStatus();
5506
5507 if (status == WorkflowConstants.STATUS_APPROVED) {
5508 Date expirationDate = article.getExpirationDate();
5509
5510 if ((expirationDate != null) && expirationDate.before(now)) {
5511 article.setExpirationDate(null);
5512 }
5513 }
5514
5515 if (status == WorkflowConstants.STATUS_EXPIRED) {
5516 article.setExpirationDate(now);
5517 }
5518
5519 article.setStatus(status);
5520 article.setStatusByUserId(user.getUserId());
5521 article.setStatusByUserName(user.getFullName());
5522 article.setStatusDate(serviceContext.getModifiedDate(now));
5523
5524 journalArticlePersistence.update(article);
5525
5526 if (hasModifiedLatestApprovedVersion(
5527 article.getGroupId(), article.getArticleId(),
5528 article.getVersion())) {
5529
5530 if (status == WorkflowConstants.STATUS_APPROVED) {
5531 updateUrlTitles(
5532 article.getGroupId(), article.getArticleId(),
5533 article.getUrlTitle());
5534
5535
5536
5537 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5538 (article.getVersion() !=
5539 JournalArticleConstants.VERSION_DEFAULT)) {
5540
5541 AssetEntry draftAssetEntry =
5542 assetEntryLocalService.fetchEntry(
5543 JournalArticle.class.getName(),
5544 article.getPrimaryKey());
5545
5546 if (draftAssetEntry != null) {
5547 long[] assetCategoryIds =
5548 draftAssetEntry.getCategoryIds();
5549 String[] assetTagNames = draftAssetEntry.getTagNames();
5550
5551 List<AssetLink> assetLinks =
5552 assetLinkLocalService.getDirectLinks(
5553 draftAssetEntry.getEntryId(),
5554 AssetLinkConstants.TYPE_RELATED);
5555
5556 long[] assetLinkEntryIds = ListUtil.toLongArray(
5557 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
5558
5559 AssetEntry assetEntry =
5560 assetEntryLocalService.updateEntry(
5561 userId, article.getGroupId(),
5562 article.getCreateDate(),
5563 article.getModifiedDate(),
5564 JournalArticle.class.getName(),
5565 article.getResourcePrimKey(), article.getUuid(),
5566 getClassTypeId(article), assetCategoryIds,
5567 assetTagNames, false, null, null, null,
5568 ContentTypes.TEXT_HTML, article.getTitle(),
5569 article.getDescription(),
5570 article.getDescription(), null,
5571 article.getLayoutUuid(), 0, 0, null, false);
5572
5573 assetLinkLocalService.updateLinks(
5574 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5575 AssetLinkConstants.TYPE_RELATED);
5576
5577 assetEntryLocalService.deleteEntry(
5578 JournalArticle.class.getName(),
5579 article.getPrimaryKey());
5580 }
5581 }
5582
5583 if (article.getClassNameId() ==
5584 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5585
5586 assetEntryLocalService.updateEntry(
5587 JournalArticle.class.getName(),
5588 article.getResourcePrimKey(), article.getDisplayDate(),
5589 article.getExpirationDate(), true);
5590 }
5591
5592
5593
5594 JSONObject extraDataJSONObject =
5595 JSONFactoryUtil.createJSONObject();
5596
5597 extraDataJSONObject.put("title", article.getTitle());
5598
5599 if (serviceContext.isCommandUpdate()) {
5600 socialActivityLocalService.addActivity(
5601 user.getUserId(), article.getGroupId(),
5602 JournalArticle.class.getName(),
5603 article.getResourcePrimKey(),
5604 JournalActivityKeys.UPDATE_ARTICLE,
5605 extraDataJSONObject.toString(), 0);
5606 }
5607 else {
5608 socialActivityLocalService.addUniqueActivity(
5609 user.getUserId(), article.getGroupId(),
5610 JournalArticle.class.getName(),
5611 article.getResourcePrimKey(),
5612 JournalActivityKeys.ADD_ARTICLE,
5613 extraDataJSONObject.toString(), 0);
5614 }
5615 }
5616 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5617 updatePreviousApprovedArticle(article);
5618 }
5619 }
5620
5621 if ((article.getClassNameId() ==
5622 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5623 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5624 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5625
5626
5627
5628 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5629 ((status == WorkflowConstants.STATUS_APPROVED) ||
5630 (status == WorkflowConstants.STATUS_DENIED))) {
5631
5632 String msg = "granted";
5633
5634 if (status == WorkflowConstants.STATUS_DENIED) {
5635 msg = "denied";
5636 }
5637
5638 try {
5639 PortletPreferences preferences =
5640 ServiceContextUtil.getPortletPreferences(
5641 serviceContext);
5642
5643 articleURL = buildArticleURL(
5644 articleURL, article.getGroupId(), article.getFolderId(),
5645 article.getArticleId());
5646
5647 sendEmail(
5648 article, articleURL, preferences, msg, serviceContext);
5649 }
5650 catch (Exception e) {
5651 _log.error(
5652 "Unable to send email to notify the change of status " +
5653 " to " + msg + " for article " + article.getId() +
5654 ": " + e.getMessage());
5655 }
5656 }
5657
5658
5659
5660 notifySubscribers(
5661 article,
5662 (String)workflowContext.get(WorkflowConstants.CONTEXT_URL),
5663 serviceContext);
5664 }
5665
5666 return article;
5667 }
5668
5669
5689 @Override
5690 public JournalArticle updateStatus(
5691 long userId, long classPK, int status,
5692 Map<String, Serializable> workflowContext,
5693 ServiceContext serviceContext)
5694 throws PortalException {
5695
5696 JournalArticle article = getArticle(classPK);
5697
5698 return journalArticleLocalService.updateStatus(
5699 userId, article, status, null, serviceContext, workflowContext);
5700 }
5701
5702
5723 @Override
5724 public JournalArticle updateStatus(
5725 long userId, long groupId, String articleId, double version,
5726 int status, String articleURL,
5727 Map<String, Serializable> workflowContext,
5728 ServiceContext serviceContext)
5729 throws PortalException {
5730
5731 JournalArticle article = journalArticlePersistence.findByG_A_V(
5732 groupId, articleId, version);
5733
5734 return journalArticleLocalService.updateStatus(
5735 userId, article, status, articleURL, serviceContext,
5736 workflowContext);
5737 }
5738
5739
5753 @Override
5754 public void updateTemplateId(
5755 long groupId, long classNameId, String oldDDMTemplateKey,
5756 String newDDMTemplateKey) {
5757
5758 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5759 groupId, classNameId, oldDDMTemplateKey);
5760
5761 for (JournalArticle article : articles) {
5762 article.setTemplateId(newDDMTemplateKey);
5763
5764 journalArticlePersistence.update(article);
5765 }
5766 }
5767
5768 protected String buildArticleURL(
5769 String articleURL, long groupId, long folderId, String articleId) {
5770
5771 StringBundler sb = new StringBundler(13);
5772
5773 sb.append(articleURL);
5774 sb.append(StringPool.AMPERSAND);
5775 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5776 sb.append("groupId=");
5777 sb.append(groupId);
5778 sb.append(StringPool.AMPERSAND);
5779 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5780 sb.append("folderId=");
5781 sb.append(folderId);
5782 sb.append(StringPool.AMPERSAND);
5783 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5784 sb.append("articleId=");
5785 sb.append(articleId);
5786
5787 return sb.toString();
5788 }
5789
5790 protected SearchContext buildSearchContext(
5791 long companyId, long groupId, List<Long> folderIds, long classNameId,
5792 String articleId, String title, String description, String content,
5793 String type, int status, String ddmStructureKey, String ddmTemplateKey,
5794 LinkedHashMap<String, Object> params, boolean andSearch, int start,
5795 int end, Sort sort) {
5796
5797 SearchContext searchContext = new SearchContext();
5798
5799 searchContext.setAndSearch(andSearch);
5800
5801 Map<String, Serializable> attributes =
5802 new HashMap<String, Serializable>();
5803
5804 attributes.put(Field.ARTICLE_ID, articleId);
5805 attributes.put(Field.CLASS_NAME_ID, classNameId);
5806 attributes.put(Field.CONTENT, content);
5807 attributes.put(Field.DESCRIPTION, description);
5808 attributes.put(Field.STATUS, status);
5809 attributes.put(Field.TITLE, title);
5810 attributes.put(Field.TYPE, type);
5811 attributes.put("ddmStructureKey", ddmStructureKey);
5812 attributes.put("ddmTemplateKey", ddmTemplateKey);
5813 attributes.put("params", params);
5814
5815 searchContext.setAttributes(attributes);
5816
5817 searchContext.setCompanyId(companyId);
5818 searchContext.setEnd(end);
5819 searchContext.setFolderIds(folderIds);
5820 searchContext.setGroupIds(new long[] {groupId});
5821 searchContext.setIncludeDiscussions(
5822 GetterUtil.getBoolean(params.get("includeDiscussions")));
5823
5824 if (params != null) {
5825 String keywords = (String)params.remove("keywords");
5826
5827 if (Validator.isNotNull(keywords)) {
5828 searchContext.setKeywords(keywords);
5829 }
5830 }
5831
5832 QueryConfig queryConfig = new QueryConfig();
5833
5834 queryConfig.setHighlightEnabled(false);
5835 queryConfig.setScoreEnabled(false);
5836
5837 searchContext.setQueryConfig(queryConfig);
5838
5839 if (sort != null) {
5840 searchContext.setSorts(sort);
5841 }
5842
5843 searchContext.setStart(start);
5844
5845 return searchContext;
5846 }
5847
5848 protected SearchContext buildSearchContext(
5849 long groupId, long userId, long creatorUserId, int status,
5850 int start, int end)
5851 throws PortalException {
5852
5853 SearchContext searchContext = new SearchContext();
5854
5855 searchContext.setAttribute(Field.STATUS, status);
5856
5857 searchContext.setAttribute("paginationType", "none");
5858
5859 if (creatorUserId > 0) {
5860 searchContext.setAttribute(
5861 Field.USER_ID, String.valueOf(creatorUserId));
5862 }
5863
5864 Group group = groupLocalService.getGroup(groupId);
5865
5866 searchContext.setCompanyId(group.getCompanyId());
5867
5868 searchContext.setEnd(end);
5869 searchContext.setGroupIds(new long[] {groupId});
5870 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
5871 searchContext.setStart(start);
5872 searchContext.setUserId(userId);
5873
5874 return searchContext;
5875 }
5876
5877 protected void checkArticlesByDisplayDate(Date displayDate)
5878 throws PortalException {
5879
5880 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5881 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5882
5883 for (JournalArticle article : articles) {
5884 ServiceContext serviceContext = new ServiceContext();
5885
5886 serviceContext.setCommand(Constants.UPDATE);
5887
5888 String layoutFullURL = PortalUtil.getLayoutFullURL(
5889 article.getGroupId(), PortletKeys.JOURNAL);
5890
5891 serviceContext.setLayoutFullURL(layoutFullURL);
5892
5893 serviceContext.setScopeGroupId(article.getGroupId());
5894
5895 journalArticleLocalService.updateStatus(
5896 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5897 null, serviceContext, new HashMap<String, Serializable>());
5898 }
5899 }
5900
5901 protected void checkArticlesByExpirationDate(Date expirationDate)
5902 throws PortalException {
5903
5904 List<JournalArticle> articles =
5905 journalArticleFinder.findByExpirationDate(
5906 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5907 new Date(
5908 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5909 new QueryDefinition<JournalArticle>(
5910 WorkflowConstants.STATUS_APPROVED));
5911
5912 if (_log.isDebugEnabled()) {
5913 _log.debug("Expiring " + articles.size() + " articles");
5914 }
5915
5916 Set<Long> companyIds = new HashSet<Long>();
5917
5918 for (JournalArticle article : articles) {
5919 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5920 List<JournalArticle> currentArticles =
5921 journalArticlePersistence.findByG_A(
5922 article.getGroupId(), article.getArticleId(),
5923 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5924 new ArticleVersionComparator(true));
5925
5926 for (JournalArticle currentArticle : currentArticles) {
5927 currentArticle.setExpirationDate(
5928 article.getExpirationDate());
5929 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5930
5931 journalArticlePersistence.update(currentArticle);
5932 }
5933 }
5934 else {
5935 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5936
5937 journalArticlePersistence.update(article);
5938 }
5939
5940 updatePreviousApprovedArticle(article);
5941
5942 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5943 JournalArticle.class);
5944
5945 indexer.reindex(article);
5946
5947 JournalContentUtil.clearCache(
5948 article.getGroupId(), article.getArticleId(),
5949 article.getTemplateId());
5950
5951 companyIds.add(article.getCompanyId());
5952 }
5953
5954 for (long companyId : companyIds) {
5955 CacheUtil.clearCache(companyId);
5956 }
5957
5958 if (_previousCheckDate == null) {
5959 _previousCheckDate = new Date(
5960 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5961 }
5962 }
5963
5964 protected void checkArticlesByReviewDate(Date reviewDate)
5965 throws PortalException {
5966
5967 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5968 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5969 _previousCheckDate);
5970
5971 if (_log.isDebugEnabled()) {
5972 _log.debug(
5973 "Sending review notifications for " + articles.size() +
5974 " articles");
5975 }
5976
5977 for (JournalArticle article : articles) {
5978 String articleURL = StringPool.BLANK;
5979
5980 long ownerId = article.getGroupId();
5981 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5982 long plid = PortletKeys.PREFS_PLID_SHARED;
5983 String portletId = PortletKeys.JOURNAL;
5984
5985 PortletPreferences preferences =
5986 portletPreferencesLocalService.getPreferences(
5987 article.getCompanyId(), ownerId, ownerType, plid,
5988 portletId);
5989
5990 sendEmail(
5991 article, articleURL, preferences, "review",
5992 new ServiceContext());
5993 }
5994 }
5995
5996 protected void checkStructure(Document contentDocument, DDMForm ddmForm)
5997 throws PortalException {
5998
5999 for (DDMFormField ddmFormField : ddmForm.getDDMFormFields()) {
6000 if (isPrivateDDMFormField(ddmFormField)) {
6001 continue;
6002 }
6003
6004 checkStructureField(ddmFormField, contentDocument.getRootElement());
6005 }
6006 }
6007
6008 protected void checkStructure(JournalArticle article)
6009 throws PortalException {
6010
6011 DDMStructure ddmStructure = article.getDDMStructure();
6012
6013 try {
6014 checkStructure(article, ddmStructure);
6015 }
6016 catch (StructureDefinitionException sde) {
6017 if (_log.isWarnEnabled()) {
6018 StringBundler sb = new StringBundler(8);
6019
6020 sb.append("Article {groupId=");
6021 sb.append(article.getGroupId());
6022 sb.append(", articleId=");
6023 sb.append(article.getArticleId());
6024 sb.append(", version=");
6025 sb.append(article.getVersion());
6026 sb.append("} has content that does not match its structure: ");
6027 sb.append(sde.getMessage());
6028
6029 _log.warn(sb.toString());
6030 }
6031 }
6032 }
6033
6034 protected void checkStructure(
6035 JournalArticle article, DDMStructure ddmStructure)
6036 throws PortalException {
6037
6038 checkStructure(article.getDocument(), ddmStructure.getDDMForm());
6039 }
6040
6041 protected void checkStructureField(
6042 DDMFormField ddmFormField, Element contentElement)
6043 throws PortalException {
6044
6045 String fieldName = ddmFormField.getName();
6046
6047 boolean hasField = false;
6048
6049 for (Element childElement : contentElement.elements()) {
6050 if (fieldName.equals(
6051 childElement.attributeValue("name", StringPool.BLANK))) {
6052
6053 hasField = true;
6054
6055 for (DDMFormField childDDMFormField :
6056 ddmFormField.getNestedDDMFormFields()) {
6057
6058 checkStructureField(childDDMFormField, childElement);
6059 }
6060
6061 break;
6062 }
6063 }
6064
6065 if (!hasField) {
6066 String contentElementType = contentElement.attributeValue(
6067 "type", StringPool.BLANK);
6068
6069 if (!contentElementType.equals("list") &&
6070 !contentElementType.equals("multi-list")) {
6071
6072 throw new StructureDefinitionException(fieldName);
6073 }
6074 }
6075 }
6076
6077 protected void copyArticleImages(
6078 JournalArticle oldArticle, JournalArticle newArticle)
6079 throws Exception {
6080
6081 Document contentDocument = oldArticle.getDocument();
6082
6083 contentDocument = contentDocument.clone();
6084
6085 XPath xPathSelector = SAXReaderUtil.createXPath(
6086 "
6087
6088 List<Node> imageNodes = xPathSelector.selectNodes(contentDocument);
6089
6090 for (Node imageNode : imageNodes) {
6091 Element imageEl = (Element)imageNode;
6092
6093 String instanceId = imageEl.attributeValue("instance-id");
6094 String name = imageEl.attributeValue("name");
6095
6096 List<Element> dynamicContentEls = imageEl.elements(
6097 "dynamic-content");
6098
6099 for (Element dynamicContentEl : dynamicContentEls) {
6100 long imageId = GetterUtil.getLong(
6101 dynamicContentEl.attributeValue("id"));
6102 String languageId = dynamicContentEl.attributeValue(
6103 "language-id");
6104
6105 Image oldImage = null;
6106
6107 try {
6108 oldImage = imageLocalService.getImage(imageId);
6109 }
6110 catch (NoSuchImageException nsie) {
6111 continue;
6112 }
6113
6114 imageId = journalArticleImageLocalService.getArticleImageId(
6115 newArticle.getGroupId(), newArticle.getArticleId(),
6116 newArticle.getVersion(), instanceId, name, languageId);
6117
6118 imageLocalService.updateImage(imageId, oldImage.getTextObj());
6119
6120 String elContent =
6121 "/image/journal/article?img_id=" + imageId + "&t=" +
6122 WebServerServletTokenUtil.getToken(imageId);
6123
6124 dynamicContentEl.setText(elContent);
6125 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
6126 }
6127 }
6128
6129 newArticle.setContent(contentDocument.formattedString());
6130 }
6131
6132 protected Map<String, String> createFieldsValuesMap(Element parentElement) {
6133 Map<String, String> fieldsValuesMap = new HashMap<String, String>();
6134
6135 List<Element> dynamicElementElements = parentElement.elements(
6136 "dynamic-element");
6137
6138 for (Element dynamicElementElement : dynamicElementElements) {
6139 String fieldName = dynamicElementElement.attributeValue(
6140 "name", StringPool.BLANK);
6141
6142 List<Element> dynamicContentElements =
6143 dynamicElementElement.elements("dynamic-content");
6144
6145 for (Element dynamicContentElement : dynamicContentElements) {
6146 String value = dynamicContentElement.getText();
6147
6148 fieldsValuesMap.put(fieldName, value);
6149 }
6150
6151 fieldsValuesMap.putAll(
6152 createFieldsValuesMap(dynamicElementElement));
6153 }
6154
6155 return fieldsValuesMap;
6156 }
6157
6158 protected Map<String, String> createFieldsValuesMap(String content) {
6159 try {
6160 Document document = SAXReaderUtil.read(content);
6161
6162 Element rootElement = document.getRootElement();
6163
6164 return createFieldsValuesMap(rootElement);
6165 }
6166 catch (DocumentException de) {
6167 throw new SystemException(de);
6168 }
6169 }
6170
6171 protected void format(
6172 User user, long groupId, String articleId, double version,
6173 boolean incrementVersion, Element root, Map<String, byte[]> images)
6174 throws PortalException {
6175
6176 for (Element element : root.elements()) {
6177 String elInstanceId = element.attributeValue(
6178 "instance-id", StringPool.BLANK);
6179 String elType = element.attributeValue("type", StringPool.BLANK);
6180
6181 if (elType.equals("document_library")) {
6182 formatDocumentLibrary(element);
6183 }
6184 else if (elType.equals("image")) {
6185 String elName = element.attributeValue(
6186 "name", StringPool.BLANK);
6187 String elIndex = element.attributeValue(
6188 "index", StringPool.BLANK);
6189
6190 String name = elName + "_" + elIndex;
6191
6192 formatImage(
6193 groupId, articleId, version, incrementVersion, element,
6194 elInstanceId, name, images);
6195 }
6196 else if (elType.equals("text_area") || elType.equals("text") ||
6197 elType.equals("text_box")) {
6198
6199 List<Element> dynamicContentElements = element.elements(
6200 "dynamic-content");
6201
6202 for (Element dynamicContentElement : dynamicContentElements) {
6203 String dynamicContent = dynamicContentElement.getText();
6204
6205 if (Validator.isNotNull(dynamicContent)) {
6206 String contentType = ContentTypes.TEXT_PLAIN;
6207
6208 if (elType.equals("text_area")) {
6209 contentType = ContentTypes.TEXT_HTML;
6210 }
6211
6212 dynamicContent = SanitizerUtil.sanitize(
6213 user.getCompanyId(), groupId, user.getUserId(),
6214 JournalArticle.class.getName(), 0, contentType,
6215 dynamicContent);
6216
6217 dynamicContentElement.clearContent();
6218
6219 dynamicContentElement.addCDATA(dynamicContent);
6220 }
6221 }
6222 }
6223
6224 format(
6225 user, groupId, articleId, version, incrementVersion, element,
6226 images);
6227 }
6228 }
6229
6230 protected String format(
6231 User user, long groupId, String articleId, double version,
6232 boolean incrementVersion, String content, String ddmStructureKey,
6233 Map<String, byte[]> images)
6234 throws PortalException {
6235
6236 Document document = null;
6237
6238 try {
6239 document = SAXReaderUtil.read(content);
6240
6241 Element rootElement = document.getRootElement();
6242
6243 format(
6244 user, groupId, articleId, version, incrementVersion,
6245 rootElement, images);
6246
6247 content = DDMXMLUtil.formatXML(document);
6248 }
6249 catch (DocumentException de) {
6250 _log.error(de, de);
6251 }
6252
6253 return content;
6254 }
6255
6256 protected void formatDocumentLibrary(Element dynamicElementElement)
6257 throws PortalException {
6258
6259 for (Element dynamicContentElement :
6260 dynamicElementElement.elements("dynamic-content")) {
6261
6262 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
6263 dynamicContentElement.getText());
6264
6265 String uuid = jsonObject.getString("uuid");
6266 long groupId = jsonObject.getLong("groupId");
6267 boolean tempFile = jsonObject.getBoolean("tempFile");
6268
6269 FileEntry fileEntry =
6270 dlAppLocalService.getFileEntryByUuidAndGroupId(uuid, groupId);
6271
6272 if (tempFile) {
6273 String fileEntryName = DLUtil.getFileName(
6274 fileEntry.getGroupId(), fileEntry.getFolderId(),
6275 fileEntry.getFileName());
6276
6277 fileEntry = dlAppLocalService.addFileEntry(
6278 fileEntry.getUserId(), fileEntry.getGroupId(), 0,
6279 fileEntryName, fileEntry.getMimeType(), fileEntryName,
6280 StringPool.BLANK, StringPool.BLANK,
6281 fileEntry.getContentStream(), fileEntry.getSize(),
6282 new ServiceContext());
6283 }
6284
6285 String previewURL = DLUtil.getPreviewURL(
6286 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
6287 false, true);
6288
6289 dynamicContentElement.clearContent();
6290
6291 dynamicContentElement.addCDATA(previewURL);
6292 }
6293 }
6294
6295 protected void formatImage(
6296 long groupId, String articleId, double version,
6297 boolean incrementVersion, Element el, String elInstanceId,
6298 String elName, Map<String, byte[]> images)
6299 throws PortalException {
6300
6301 List<Element> imageContents = el.elements("dynamic-content");
6302
6303 for (Element dynamicContent : imageContents) {
6304 String elLanguage = dynamicContent.attributeValue(
6305 "language-id", StringPool.BLANK);
6306
6307 if (!elLanguage.equals(StringPool.BLANK)) {
6308 elLanguage = "_" + elLanguage;
6309 }
6310
6311 long imageId = journalArticleImageLocalService.getArticleImageId(
6312 groupId, articleId, version, elInstanceId, elName, elLanguage);
6313
6314 if (dynamicContent.getText().equals("delete") ||
6315 Validator.isNull(dynamicContent.getText())) {
6316
6317 dynamicContent.setText(StringPool.BLANK);
6318
6319 imageLocalService.deleteImage(imageId);
6320
6321 String defaultElLanguage = "";
6322
6323 if (Validator.isNull(elLanguage)) {
6324 defaultElLanguage =
6325 "_" +
6326 LocaleUtil.toLanguageId(
6327 LocaleUtil.getSiteDefault());
6328 }
6329
6330 long defaultImageId =
6331 journalArticleImageLocalService.getArticleImageId(
6332 groupId, articleId, version, elInstanceId, elName,
6333 defaultElLanguage);
6334
6335 imageLocalService.deleteImage(defaultImageId);
6336
6337 continue;
6338 }
6339
6340 String elContent =
6341 "/image/journal/article?img_id=" + imageId + "&t=" +
6342 WebServerServletTokenUtil.getToken(imageId);
6343
6344 byte[] bytes = null;
6345
6346 if (images != null) {
6347 bytes = images.get(elInstanceId + "_" + elName + elLanguage);
6348 }
6349
6350 if (ArrayUtil.isNotEmpty(bytes)) {
6351 dynamicContent.setText(elContent);
6352 dynamicContent.addAttribute("id", String.valueOf(imageId));
6353
6354 imageLocalService.updateImage(imageId, bytes);
6355
6356 continue;
6357 }
6358
6359 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
6360 incrementVersion) {
6361
6362 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
6363
6364 long oldImageId = 0;
6365
6366 if ((oldVersion >= 1) && incrementVersion) {
6367 oldImageId =
6368 journalArticleImageLocalService.getArticleImageId(
6369 groupId, articleId, oldVersion, elInstanceId,
6370 elName, elLanguage);
6371 }
6372
6373 Image oldImage = null;
6374
6375 if (oldImageId > 0) {
6376 oldImage = imageLocalService.getImage(oldImageId);
6377 }
6378
6379 if (oldImage != null) {
6380 dynamicContent.setText(elContent);
6381 dynamicContent.addAttribute("id", String.valueOf(imageId));
6382
6383 bytes = oldImage.getTextObj();
6384
6385 imageLocalService.updateImage(imageId, bytes);
6386 }
6387 else if (dynamicContent.getText().equals("update")) {
6388 dynamicContent.setText(StringPool.BLANK);
6389 }
6390
6391 continue;
6392 }
6393
6394 Image image = imageLocalService.getImage(imageId);
6395
6396 if (image != null) {
6397 dynamicContent.setText(elContent);
6398 dynamicContent.addAttribute("id", String.valueOf(imageId));
6399
6400 continue;
6401 }
6402 else if (dynamicContent.getText().equals("update")) {
6403 dynamicContent.setText(StringPool.BLANK);
6404
6405 continue;
6406 }
6407
6408 long contentImageId = GetterUtil.getLong(
6409 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
6410
6411 if (contentImageId <= 0) {
6412 contentImageId = GetterUtil.getLong(
6413 HttpUtil.getParameter(
6414 dynamicContent.getText(), "img_id", false));
6415 }
6416
6417 if (contentImageId > 0) {
6418 image = imageLocalService.getImage(contentImageId);
6419
6420 if (image != null) {
6421 dynamicContent.addAttribute(
6422 "id", String.valueOf(contentImageId));
6423
6424 continue;
6425 }
6426 }
6427
6428 String defaultElLanguage = "";
6429
6430 if (Validator.isNull(elLanguage)) {
6431 defaultElLanguage =
6432 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6433 }
6434
6435 long defaultImageId =
6436 journalArticleImageLocalService.getArticleImageId(
6437 groupId, articleId, version, elInstanceId, elName,
6438 defaultElLanguage);
6439
6440 Image defaultImage = imageLocalService.getImage(defaultImageId);
6441
6442 if (defaultImage != null) {
6443 dynamicContent.setText(elContent);
6444 dynamicContent.addAttribute(
6445 "id", String.valueOf(defaultImageId));
6446
6447 bytes = defaultImage.getTextObj();
6448
6449 imageLocalService.updateImage(defaultImageId, bytes);
6450
6451 continue;
6452 }
6453
6454 if (Validator.isNotNull(elLanguage)) {
6455 dynamicContent.setText(StringPool.BLANK);
6456 }
6457 }
6458 }
6459
6460 protected Locale getArticleDefaultLocale(
6461 String content, ServiceContext serviceContext) {
6462
6463 String defaultLanguageId = ParamUtil.getString(
6464 serviceContext, "defaultLanguageId");
6465
6466 if (Validator.isNull(defaultLanguageId)) {
6467 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
6468 }
6469
6470 if (Validator.isNotNull(defaultLanguageId)) {
6471 return LocaleUtil.fromLanguageId(defaultLanguageId);
6472 }
6473
6474 return LocaleUtil.getSiteDefault();
6475 }
6476
6477 protected JournalArticleDisplay getArticleDisplay(
6478 JournalArticle article, String ddmTemplateKey, String viewMode,
6479 String languageId, int page,
6480 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay,
6481 boolean propagateException)
6482 throws PortalException {
6483
6484 String content = null;
6485
6486 if (page < 1) {
6487 page = 1;
6488 }
6489
6490 int numberOfPages = 1;
6491 boolean paginate = false;
6492 boolean pageFlow = false;
6493
6494 boolean cacheable = true;
6495
6496 Map<String, String> tokens = JournalUtil.getTokens(
6497 article.getGroupId(), portletRequestModel, themeDisplay);
6498
6499 if ((themeDisplay == null) && (portletRequestModel == null)) {
6500 tokens.put("company_id", String.valueOf(article.getCompanyId()));
6501
6502 Group companyGroup = groupLocalService.getCompanyGroup(
6503 article.getCompanyId());
6504
6505 tokens.put(
6506 "article_group_id", String.valueOf(article.getGroupId()));
6507 tokens.put(
6508 "company_group_id", String.valueOf(companyGroup.getGroupId()));
6509
6510
6511
6512 tokens.put("group_id", String.valueOf(article.getGroupId()));
6513 }
6514
6515 tokens.put(
6516 "article_resource_pk",
6517 String.valueOf(article.getResourcePrimKey()));
6518
6519 String defaultDDMTemplateKey = article.getTemplateId();
6520
6521 if (Validator.isNull(ddmTemplateKey)) {
6522 ddmTemplateKey = defaultDDMTemplateKey;
6523 }
6524
6525 tokens.put("structure_id", article.getStructureId());
6526 tokens.put("template_id", ddmTemplateKey);
6527
6528 Document document = article.getDocument();
6529
6530 document = document.clone();
6531
6532 Element rootElement = document.getRootElement();
6533
6534 List<Element> pages = rootElement.elements("page");
6535
6536 if (!pages.isEmpty()) {
6537 pageFlow = true;
6538
6539 String targetPage = null;
6540
6541 Map<String, String[]> parameters =
6542 portletRequestModel.getParameters();
6543
6544 if (parameters != null) {
6545 String[] values = parameters.get("targetPage");
6546
6547 if ((values != null) && (values.length > 0)) {
6548 targetPage = values[0];
6549 }
6550 }
6551
6552 Element pageElement = null;
6553
6554 if (Validator.isNotNull(targetPage)) {
6555 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
6556
6557 XPath xPathSelector = SAXReaderUtil.createXPath(
6558 "/root/page[@id = " + targetPage + "]");
6559
6560 pageElement = (Element)xPathSelector.selectSingleNode(document);
6561 }
6562
6563 if (pageElement != null) {
6564 document = SAXReaderUtil.createDocument(pageElement);
6565
6566 rootElement = document.getRootElement();
6567
6568 numberOfPages = pages.size();
6569 }
6570 else {
6571 if (page > pages.size()) {
6572 page = 1;
6573 }
6574
6575 pageElement = pages.get(page - 1);
6576
6577 document = SAXReaderUtil.createDocument(pageElement);
6578
6579 rootElement = document.getRootElement();
6580
6581 numberOfPages = pages.size();
6582 paginate = true;
6583 }
6584 }
6585
6586 JournalUtil.addAllReservedEls(
6587 rootElement, tokens, article, languageId, themeDisplay);
6588
6589 try {
6590 if (_log.isDebugEnabled()) {
6591 _log.debug(
6592 "Transforming " + article.getArticleId() + " " +
6593 article.getVersion() + " " + languageId);
6594 }
6595
6596
6597
6598
6599
6600
6601 DDMTemplate ddmTemplate = null;
6602
6603 try {
6604 ddmTemplate = ddmTemplateLocalService.getTemplate(
6605 PortalUtil.getSiteGroupId(article.getGroupId()),
6606 classNameLocalService.getClassNameId(DDMStructure.class),
6607 ddmTemplateKey, true);
6608
6609 Group companyGroup = groupLocalService.getCompanyGroup(
6610 article.getCompanyId());
6611
6612 if (companyGroup.getGroupId() == ddmTemplate.getGroupId()) {
6613 tokens.put(
6614 "company_group_id",
6615 String.valueOf(companyGroup.getGroupId()));
6616 }
6617 }
6618 catch (NoSuchTemplateException nste) {
6619 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
6620 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6621 PortalUtil.getSiteGroupId(article.getGroupId()),
6622 classNameLocalService.getClassNameId(
6623 DDMStructure.class),
6624 defaultDDMTemplateKey);
6625 }
6626 else {
6627 throw nste;
6628 }
6629 }
6630
6631 String script = ddmTemplate.getScript();
6632 String langType = ddmTemplate.getLanguage();
6633 cacheable = ddmTemplate.isCacheable();
6634
6635 if (propagateException) {
6636 content = JournalUtil.doTransform(
6637 themeDisplay, tokens, viewMode, languageId, document,
6638 portletRequestModel, script, langType);
6639 }
6640 else {
6641 content = JournalUtil.transform(
6642 themeDisplay, tokens, viewMode, languageId, document,
6643 portletRequestModel, script, langType);
6644 }
6645
6646 if (!pageFlow) {
6647 String[] pieces = StringUtil.split(
6648 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
6649
6650 if (pieces.length > 1) {
6651 if (page > pieces.length) {
6652 page = 1;
6653 }
6654
6655 content = pieces[page - 1];
6656 numberOfPages = pieces.length;
6657 paginate = true;
6658 }
6659 }
6660 }
6661 catch (Exception e) {
6662 throw new SystemException(e);
6663 }
6664
6665 return new JournalArticleDisplayImpl(
6666 article.getCompanyId(), article.getId(),
6667 article.getResourcePrimKey(), article.getGroupId(),
6668 article.getUserId(), article.getArticleId(), article.getVersion(),
6669 article.getTitle(languageId), article.getUrlTitle(),
6670 article.getDescription(languageId),
6671 article.getAvailableLanguageIds(), content, article.getType(),
6672 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
6673 article.getSmallImageId(), article.getSmallImageURL(),
6674 numberOfPages, page, paginate, cacheable);
6675 }
6676
6677 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
6678 List<JournalArticle> articles) {
6679
6680 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
6681 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
6682
6683 for (JournalArticle article : articles) {
6684 int status = article.getStatus();
6685
6686 if (status == WorkflowConstants.STATUS_PENDING) {
6687 status = WorkflowConstants.STATUS_DRAFT;
6688 }
6689
6690 ObjectValuePair<Long, Integer> articleVersionStatusOVP =
6691 new ObjectValuePair<Long, Integer>(article.getId(), status);
6692
6693 articleVersionStatusOVPs.add(articleVersionStatusOVP);
6694 }
6695
6696 return articleVersionStatusOVPs;
6697 }
6698
6699 protected long getClassTypeId(JournalArticle article)
6700 throws PortalException {
6701
6702 long classNameId = classNameLocalService.getClassNameId(
6703 JournalArticle.class);
6704
6705 DDMStructure ddmStructure = ddmStructureLocalService.fetchStructure(
6706 article.getGroupId(), classNameId, article.getStructureId(), true);
6707
6708 return ddmStructure.getStructureId();
6709 }
6710
6711 protected JournalArticle getFirstArticle(
6712 long groupId, String articleId, int status,
6713 OrderByComparator<JournalArticle> orderByComparator)
6714 throws PortalException {
6715
6716 if (status == WorkflowConstants.STATUS_ANY) {
6717 return journalArticlePersistence.findByG_A_NotST_First(
6718 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
6719 orderByComparator);
6720 }
6721 else {
6722 return journalArticlePersistence.findByG_A_ST_First(
6723 groupId, articleId, status, orderByComparator);
6724 }
6725 }
6726
6727 protected String getUniqueUrlTitle(
6728 long id, long groupId, String articleId, String title)
6729 throws PortalException {
6730
6731 String urlTitle = JournalUtil.getUrlTitle(id, title);
6732
6733 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6734 }
6735
6736 protected String getUniqueUrlTitle(
6737 long id, String articleId, String title, String oldUrlTitle,
6738 ServiceContext serviceContext)
6739 throws PortalException {
6740
6741 String serviceContextUrlTitle = ParamUtil.getString(
6742 serviceContext, "urlTitle");
6743
6744 String urlTitle = null;
6745
6746 if (Validator.isNotNull(serviceContextUrlTitle)) {
6747 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6748 }
6749 else if (Validator.isNotNull(oldUrlTitle)) {
6750 return oldUrlTitle;
6751 }
6752 else {
6753 urlTitle = getUniqueUrlTitle(
6754 id, serviceContext.getScopeGroupId(), articleId, title);
6755 }
6756
6757 JournalArticle urlTitleArticle = null;
6758
6759 try {
6760 urlTitleArticle = getArticleByUrlTitle(
6761 serviceContext.getScopeGroupId(), urlTitle);
6762 }
6763 catch (NoSuchArticleException nsae) {
6764 }
6765
6766 if ((urlTitleArticle != null) &&
6767 !Validator.equals(
6768 urlTitleArticle.getArticleId(), articleId)) {
6769
6770 urlTitle = getUniqueUrlTitle(
6771 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6772 }
6773
6774 return urlTitle;
6775 }
6776
6777 protected boolean hasModifiedLatestApprovedVersion(
6778 long groupId, String articleId, double version)
6779 throws PortalException {
6780
6781 double latestApprovedVersion;
6782
6783 try {
6784 latestApprovedVersion = getLatestVersion(
6785 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6786
6787 if (version >= latestApprovedVersion) {
6788 return true;
6789 }
6790 else {
6791 return false;
6792 }
6793 }
6794 catch (NoSuchArticleException nsae) {
6795 return true;
6796 }
6797 }
6798
6799 protected boolean isPrivateDDMFormField(DDMFormField ddmFormField) {
6800 String name = ddmFormField.getName();
6801
6802 if (name.startsWith(StringPool.UNDERLINE)) {
6803 return true;
6804 }
6805
6806 return false;
6807 }
6808
6809 protected void notifySubscribers(
6810 JournalArticle article, String articleURL,
6811 ServiceContext serviceContext)
6812 throws PortalException {
6813
6814 if (!article.isApproved() || Validator.isNull(articleURL)) {
6815 return;
6816 }
6817
6818 String articleTitle = article.getTitle(serviceContext.getLanguageId());
6819
6820 articleURL = buildArticleURL(
6821 articleURL, article.getGroupId(), article.getFolderId(),
6822 article.getArticleId());
6823
6824 PortletPreferences preferences =
6825 ServiceContextUtil.getPortletPreferences(serviceContext);
6826
6827 if (preferences == null) {
6828 long ownerId = article.getGroupId();
6829 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6830 long plid = PortletKeys.PREFS_PLID_SHARED;
6831 String portletId = PortletKeys.JOURNAL;
6832 String defaultPreferences = null;
6833
6834 preferences = portletPreferencesLocalService.getPreferences(
6835 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6836 defaultPreferences);
6837 }
6838
6839 if ((article.getVersion() == 1.0) &&
6840 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6841 }
6842 else if ((article.getVersion() != 1.0) &&
6843 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6844 }
6845 else {
6846 return;
6847 }
6848
6849 String fromName = JournalUtil.getEmailFromName(
6850 preferences, article.getCompanyId());
6851 String fromAddress = JournalUtil.getEmailFromAddress(
6852 preferences, article.getCompanyId());
6853
6854 Map<Locale, String> localizedSubjectMap = null;
6855 Map<Locale, String> localizedBodyMap = null;
6856
6857 if (article.getVersion() == 1.0) {
6858 localizedSubjectMap = JournalUtil.getEmailArticleAddedSubjectMap(
6859 preferences);
6860 localizedBodyMap = JournalUtil.getEmailArticleAddedBodyMap(
6861 preferences);
6862 }
6863 else {
6864 localizedSubjectMap = JournalUtil.getEmailArticleUpdatedSubjectMap(
6865 preferences);
6866 localizedBodyMap = JournalUtil.getEmailArticleUpdatedBodyMap(
6867 preferences);
6868 }
6869
6870 String articleContent = StringPool.BLANK;
6871 String articleDiffs = StringPool.BLANK;
6872
6873 JournalArticle previousApprovedArticle = getPreviousApprovedArticle(
6874 article);
6875
6876 try {
6877 PortletRequestModel portletRequestModel = new PortletRequestModel(
6878 serviceContext.getLiferayPortletRequest(),
6879 serviceContext.getLiferayPortletResponse());
6880
6881 JournalArticleDisplay articleDisplay = getArticleDisplay(
6882 article, null, Constants.VIEW,
6883 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault()), 1,
6884 portletRequestModel, serviceContext.getThemeDisplay());
6885
6886 articleContent = articleDisplay.getContent();
6887
6888 articleDiffs = JournalUtil.diffHtml(
6889 article.getGroupId(), article.getArticleId(),
6890 previousApprovedArticle.getVersion(), article.getVersion(),
6891 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault()),
6892 portletRequestModel, serviceContext.getThemeDisplay());
6893 }
6894 catch (Exception e) {
6895 }
6896
6897 SubscriptionSender subscriptionSender = new SubscriptionSender();
6898
6899 subscriptionSender.setClassName(article.getModelClassName());
6900 subscriptionSender.setClassPK(article.getId());
6901 subscriptionSender.setCompanyId(article.getCompanyId());
6902 subscriptionSender.setContextAttribute(
6903 "[$ARTICLE_CONTENT$]", articleContent, false);
6904 subscriptionSender.setContextAttribute(
6905 "[$ARTICLE_DIFFS$]", DiffHtmlUtil.replaceStyles(articleDiffs),
6906 false);
6907 subscriptionSender.setContextAttributes(
6908 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6909 articleTitle, "[$ARTICLE_URL$]", articleURL, "[$ARTICLE_VERSION$]",
6910 article.getVersion());
6911 subscriptionSender.setContextUserPrefix("ARTICLE");
6912 subscriptionSender.setEntryTitle(articleTitle);
6913 subscriptionSender.setEntryURL(articleURL);
6914 subscriptionSender.setFrom(fromAddress, fromName);
6915 subscriptionSender.setHtmlFormat(true);
6916 subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
6917 subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
6918 subscriptionSender.setMailId("journal_article", article.getId());
6919
6920 int notificationType =
6921 UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
6922
6923 if (serviceContext.isCommandUpdate()) {
6924 notificationType =
6925 UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
6926 }
6927
6928 subscriptionSender.setNotificationType(notificationType);
6929
6930 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6931 subscriptionSender.setReplyToAddress(fromAddress);
6932 subscriptionSender.setScopeGroupId(article.getGroupId());
6933 subscriptionSender.setServiceContext(serviceContext);
6934 subscriptionSender.setUserId(article.getUserId());
6935
6936 JournalFolder folder = article.getFolder();
6937
6938 subscriptionSender.addPersistedSubscribers(
6939 JournalFolder.class.getName(), article.getGroupId());
6940
6941 if (folder != null) {
6942 subscriptionSender.addPersistedSubscribers(
6943 JournalFolder.class.getName(), folder.getFolderId());
6944
6945 for (Long ancestorFolderId : folder.getAncestorFolderIds()) {
6946 subscriptionSender.addPersistedSubscribers(
6947 JournalFolder.class.getName(), ancestorFolderId);
6948 }
6949 }
6950
6951 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
6952 article.getGroupId(),
6953 classNameLocalService.getClassNameId(JournalArticle.class),
6954 article.getStructureId(), true);
6955
6956 subscriptionSender.addPersistedSubscribers(
6957 DDMStructure.class.getName(), ddmStructure.getStructureId());
6958
6959 subscriptionSender.addPersistedSubscribers(
6960 JournalArticle.class.getName(), article.getResourcePrimKey());
6961
6962 subscriptionSender.flushNotificationsAsync();
6963 }
6964
6965 protected void saveImages(
6966 boolean smallImage, long smallImageId, File smallImageFile,
6967 byte[] smallImageBytes)
6968 throws PortalException {
6969
6970 if (smallImage) {
6971 if ((smallImageFile != null) && (smallImageBytes != null)) {
6972 imageLocalService.updateImage(smallImageId, smallImageBytes);
6973 }
6974 }
6975 else {
6976 imageLocalService.deleteImage(smallImageId);
6977 }
6978 }
6979
6980 protected BaseModelSearchResult<JournalArticle> searchJournalArticles(
6981 SearchContext searchContext)
6982 throws PortalException {
6983
6984 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6985 JournalArticle.class);
6986
6987 for (int i = 0; i < 10; i++) {
6988 Hits hits = indexer.search(
6989 searchContext, JournalUtil.SELECTED_FIELD_NAMES);
6990
6991 List<JournalArticle> articles = JournalUtil.getArticles(hits);
6992
6993 if (articles != null) {
6994 return new BaseModelSearchResult<JournalArticle>(
6995 articles, hits.getLength());
6996 }
6997 }
6998
6999 throw new SearchException(
7000 "Unable to fix the search index after 10 attempts");
7001 }
7002
7003 protected void sendEmail(
7004 JournalArticle article, String articleURL,
7005 PortletPreferences preferences, String emailType,
7006 ServiceContext serviceContext)
7007 throws PortalException {
7008
7009 if (preferences == null) {
7010 return;
7011 }
7012 else if (emailType.equals("denied") &&
7013 JournalUtil.getEmailArticleApprovalDeniedEnabled(
7014 preferences)) {
7015 }
7016 else if (emailType.equals("granted") &&
7017 JournalUtil.getEmailArticleApprovalGrantedEnabled(
7018 preferences)) {
7019 }
7020 else if (emailType.equals("requested") &&
7021 JournalUtil.getEmailArticleApprovalRequestedEnabled(
7022 preferences)) {
7023 }
7024 else if (emailType.equals("review") &&
7025 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
7026 }
7027 else {
7028 return;
7029 }
7030
7031 Company company = companyPersistence.findByPrimaryKey(
7032 article.getCompanyId());
7033
7034 User user = userPersistence.findByPrimaryKey(article.getUserId());
7035
7036 String fromName = JournalUtil.getEmailFromName(
7037 preferences, article.getCompanyId());
7038 String fromAddress = JournalUtil.getEmailFromAddress(
7039 preferences, article.getCompanyId());
7040
7041 String toName = user.getFullName();
7042 String toAddress = user.getEmailAddress();
7043
7044 if (emailType.equals("requested")) {
7045 String tempToName = fromName;
7046 String tempToAddress = fromAddress;
7047
7048 fromName = toName;
7049 fromAddress = toAddress;
7050
7051 toName = tempToName;
7052 toAddress = tempToAddress;
7053 }
7054
7055 Map<Locale, String> localizedSubjectMap = null;
7056 Map<Locale, String> localizedBodyMap = null;
7057
7058 if (emailType.equals("denied")) {
7059 localizedSubjectMap =
7060 JournalUtil.getEmailArticleApprovalDeniedSubjectMap(
7061 preferences);
7062 localizedBodyMap = JournalUtil.getEmailArticleApprovalDeniedBodyMap(
7063 preferences);
7064 }
7065 else if (emailType.equals("granted")) {
7066 localizedSubjectMap =
7067 JournalUtil.getEmailArticleApprovalGrantedSubjectMap(
7068 preferences);
7069 localizedBodyMap =
7070 JournalUtil.getEmailArticleApprovalGrantedBodyMap(preferences);
7071 }
7072 else if (emailType.equals("requested")) {
7073 localizedSubjectMap =
7074 JournalUtil.getEmailArticleApprovalRequestedSubjectMap(
7075 preferences);
7076 localizedBodyMap =
7077 JournalUtil.getEmailArticleApprovalRequestedBodyMap(
7078 preferences);
7079 }
7080 else if (emailType.equals("review")) {
7081 localizedSubjectMap = JournalUtil.getEmailArticleReviewSubjectMap(
7082 preferences);
7083 localizedBodyMap = JournalUtil.getEmailArticleReviewBodyMap(
7084 preferences);
7085 }
7086
7087 SubscriptionSender subscriptionSender = new SubscriptionSender();
7088
7089 subscriptionSender.setCompanyId(company.getCompanyId());
7090 subscriptionSender.setContextAttributes(
7091 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
7092 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
7093 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
7094 "[$ARTICLE_VERSION$]", article.getVersion());
7095 subscriptionSender.setContextUserPrefix("ARTICLE");
7096 subscriptionSender.setFrom(fromAddress, fromName);
7097 subscriptionSender.setHtmlFormat(true);
7098 subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
7099 subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
7100 subscriptionSender.setMailId("journal_article", article.getId());
7101 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
7102 subscriptionSender.setScopeGroupId(article.getGroupId());
7103 subscriptionSender.setServiceContext(serviceContext);
7104 subscriptionSender.setUserId(article.getUserId());
7105
7106 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
7107
7108 subscriptionSender.flushNotificationsAsync();
7109 }
7110
7111 protected void startWorkflowInstance(
7112 long userId, JournalArticle article, ServiceContext serviceContext)
7113 throws PortalException {
7114
7115 Map<String, Serializable> workflowContext =
7116 new HashMap<String, Serializable>();
7117
7118 workflowContext.put(
7119 WorkflowConstants.CONTEXT_URL,
7120 PortalUtil.getControlPanelFullURL(
7121 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null));
7122
7123 WorkflowHandlerRegistryUtil.startWorkflowInstance(
7124 article.getCompanyId(), article.getGroupId(), userId,
7125 JournalArticle.class.getName(), article.getId(), article,
7126 serviceContext, workflowContext);
7127 }
7128
7129 protected void updateDDMFormFieldPredefinedValue(
7130 DDMFormField ddmFormField, String ddmFormFieldValue) {
7131
7132 LocalizedValue predefinedValue = ddmFormField.getPredefinedValue();
7133
7134 for (Locale locale : predefinedValue.getAvailableLocales()) {
7135 predefinedValue.addString(locale, ddmFormFieldValue);
7136 }
7137 }
7138
7139 protected void updateDDMStructurePredefinedValues(
7140 long ddmStructureId, String content, ServiceContext serviceContext) {
7141
7142 DDMStructure ddmStructure = ddmStructureLocalService.fetchDDMStructure(
7143 ddmStructureId);
7144
7145 if (ddmStructure == null) {
7146 return;
7147 }
7148
7149 DDMForm ddmForm = ddmStructure.getDDMForm();
7150
7151 Map<String, DDMFormField> ddmFormFieldsMap =
7152 ddmStructure.getFullHierarchyDDMFormFieldsMap(true);
7153
7154 Map<String, String> fieldsValuesMap = createFieldsValuesMap(content);
7155
7156 for (Map.Entry<String, String> fieldValue :
7157 fieldsValuesMap.entrySet()) {
7158
7159 String ddmFormFieldName = fieldValue.getKey();
7160 String ddmFormFieldValue = fieldValue.getValue();
7161
7162 updateDDMFormFieldPredefinedValue(
7163 ddmFormFieldsMap.get(ddmFormFieldName), ddmFormFieldValue);
7164 }
7165
7166 ddmStructure.updateDDMForm(ddmForm);
7167
7168 ddmStructureLocalService.updateDDMStructure(ddmStructure);
7169 }
7170
7171 protected void updatePreviousApprovedArticle(JournalArticle article)
7172 throws PortalException {
7173
7174 JournalArticle previousApprovedArticle = getPreviousApprovedArticle(
7175 article);
7176
7177 if (previousApprovedArticle.getVersion() == article.getVersion()) {
7178 assetEntryLocalService.updateVisible(
7179 JournalArticle.class.getName(), article.getResourcePrimKey(),
7180 false);
7181 }
7182 else {
7183 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
7184 JournalArticle.class.getName(), article.getResourcePrimKey(),
7185 previousApprovedArticle.getDisplayDate(),
7186 previousApprovedArticle.getExpirationDate(), true);
7187
7188 assetEntry.setModifiedDate(
7189 previousApprovedArticle.getModifiedDate());
7190 assetEntry.setTitle(previousApprovedArticle.getTitle());
7191
7192 assetEntryPersistence.update(assetEntry);
7193 }
7194 }
7195
7196 protected void updateUrlTitles(
7197 long groupId, String articleId, String urlTitle)
7198 throws PortalException {
7199
7200 JournalArticle firstArticle = journalArticlePersistence.findByG_A_First(
7201 groupId, articleId, new ArticleVersionComparator(false));
7202
7203 if (firstArticle.getUrlTitle().equals(urlTitle)) {
7204 return;
7205 }
7206
7207 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
7208 groupId, articleId);
7209
7210 for (JournalArticle article : articles) {
7211 if (!article.getUrlTitle().equals(urlTitle)) {
7212 article.setUrlTitle(urlTitle);
7213
7214 journalArticlePersistence.update(article);
7215 }
7216 }
7217 }
7218
7219 protected void validate(
7220 long companyId, long groupId, long classNameId,
7221 Map<Locale, String> titleMap, String content, String type,
7222 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
7223 boolean smallImage, String smallImageURL, File smallImageFile,
7224 byte[] smallImageBytes, ServiceContext serviceContext)
7225 throws PortalException {
7226
7227 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
7228 LocalizationUtil.getDefaultLanguageId(content));
7229
7230 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
7231
7232 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
7233 LocaleException le = new LocaleException(
7234 LocaleException.TYPE_CONTENT,
7235 "The locale " + articleDefaultLocale +
7236 " is not available in site with groupId" + groupId);
7237
7238 Locale[] sourceAvailableLocales = {articleDefaultLocale};
7239
7240 le.setSourceAvailableLocales(sourceAvailableLocales);
7241 le.setTargetAvailableLocales(availableLocales);
7242
7243 throw le;
7244 }
7245
7246 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
7247 (titleMap.isEmpty() ||
7248 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
7249
7250 throw new ArticleTitleException();
7251 }
7252 else if (Validator.isNull(type)) {
7253 throw new ArticleTypeException();
7254 }
7255
7256 validateContent(content);
7257
7258 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7259 PortalUtil.getSiteGroupId(groupId),
7260 classNameLocalService.getClassNameId(JournalArticle.class),
7261 ddmStructureKey, true);
7262
7263 validateDDMStructureFields(ddmStructure, classNameId, serviceContext);
7264
7265 if (Validator.isNotNull(ddmTemplateKey)) {
7266 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
7267 PortalUtil.getSiteGroupId(groupId),
7268 classNameLocalService.getClassNameId(DDMStructure.class),
7269 ddmTemplateKey, true);
7270
7271 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
7272 throw new NoSuchTemplateException(
7273 "{templateKey=" + ddmTemplateKey + "}");
7274 }
7275 }
7276 else if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
7277 throw new NoSuchTemplateException();
7278 }
7279
7280 if ((expirationDate != null) && expirationDate.before(new Date()) &&
7281 !ExportImportThreadLocal.isImportInProcess()) {
7282
7283 throw new ArticleExpirationDateException();
7284 }
7285
7286 String[] imageExtensions = PrefsPropsUtil.getStringArray(
7287 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
7288
7289 if (!smallImage || Validator.isNotNull(smallImageURL) ||
7290 (smallImageFile == null) || (smallImageBytes == null)) {
7291
7292 return;
7293 }
7294
7295 String smallImageName = smallImageFile.getName();
7296
7297 if (smallImageName != null) {
7298 boolean validSmallImageExtension = false;
7299
7300 for (String _imageExtension : imageExtensions) {
7301 if (StringPool.STAR.equals(_imageExtension) ||
7302 StringUtil.endsWith(smallImageName, _imageExtension)) {
7303
7304 validSmallImageExtension = true;
7305
7306 break;
7307 }
7308 }
7309
7310 if (!validSmallImageExtension) {
7311 throw new ArticleSmallImageNameException(smallImageName);
7312 }
7313 }
7314
7315 long smallImageMaxSize = PrefsPropsUtil.getLong(
7316 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
7317
7318 if ((smallImageMaxSize > 0) &&
7319 ((smallImageBytes == null) ||
7320 (smallImageBytes.length > smallImageMaxSize))) {
7321
7322 throw new ArticleSmallImageSizeException();
7323 }
7324 }
7325
7326 protected void validate(
7327 long companyId, long groupId, long classNameId, String articleId,
7328 boolean autoArticleId, double version, Map<Locale, String> titleMap,
7329 String content, String type, String ddmStructureKey,
7330 String ddmTemplateKey, Date expirationDate, boolean smallImage,
7331 String smallImageURL, File smallImageFile, byte[] smallImageBytes,
7332 ServiceContext serviceContext)
7333 throws PortalException {
7334
7335 if (!autoArticleId) {
7336 validate(articleId);
7337 }
7338
7339 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
7340 groupId, articleId, version);
7341
7342 if (article != null) {
7343 StringBundler sb = new StringBundler(7);
7344
7345 sb.append("{groupId=");
7346 sb.append(groupId);
7347 sb.append(", articleId=");
7348 sb.append(articleId);
7349 sb.append(", version=");
7350 sb.append(version);
7351 sb.append("}");
7352
7353 throw new DuplicateArticleIdException(sb.toString());
7354 }
7355
7356 validate(
7357 companyId, groupId, classNameId, titleMap, content, type,
7358 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
7359 smallImageURL, smallImageFile, smallImageBytes, serviceContext);
7360 }
7361
7362 protected void validate(String articleId) throws PortalException {
7363 if (Validator.isNull(articleId) ||
7364 (articleId.indexOf(CharPool.COMMA) != -1) ||
7365 (articleId.indexOf(CharPool.SPACE) != -1)) {
7366
7367 throw new ArticleIdException();
7368 }
7369 }
7370
7371 protected void validateContent(String content) throws PortalException {
7372 if (Validator.isNull(content)) {
7373 throw new ArticleContentException("Content is null");
7374 }
7375
7376 try {
7377 SAXReaderUtil.read(content);
7378 }
7379 catch (DocumentException de) {
7380 if (_log.isDebugEnabled()) {
7381 _log.debug("Invalid content:\n" + content);
7382 }
7383
7384 throw new ArticleContentException(
7385 "Unable to read content with an XML parser", de);
7386 }
7387 }
7388
7389 protected void validateDDMStructureFields(
7390 DDMStructure ddmStructure, long classNameId,
7391 ServiceContext serviceContext)
7392 throws PortalException {
7393
7394 Fields fields = DDMUtil.getFields(
7395 ddmStructure.getStructureId(), serviceContext);
7396
7397 for (com.liferay.portlet.dynamicdatamapping.storage.Field field :
7398 fields) {
7399
7400 if (!ddmStructure.hasField(field.getName())) {
7401 throw new StorageFieldNameException();
7402 }
7403
7404 if (ddmStructure.getFieldRequired(field.getName()) &&
7405 Validator.isNull(field.getValue()) &&
7406 (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT)) {
7407
7408 throw new StorageFieldRequiredException();
7409 }
7410 }
7411 }
7412
7413 protected void validateDDMStructureId(
7414 long groupId, long folderId, String ddmStructureKey)
7415 throws PortalException {
7416
7417 int restrictionType = JournalUtil.getRestrictionType(folderId);
7418
7419 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7420 PortalUtil.getSiteGroupId(groupId),
7421 classNameLocalService.getClassNameId(JournalArticle.class),
7422 ddmStructureKey, true);
7423
7424 List<DDMStructure> folderDDMStructures =
7425 ddmStructureLocalService.getJournalFolderStructures(
7426 PortalUtil.getCurrentAndAncestorSiteGroupIds(groupId), folderId,
7427 restrictionType);
7428
7429 for (DDMStructure folderDDMStructure : folderDDMStructures) {
7430 if (folderDDMStructure.getStructureId() ==
7431 ddmStructure.getStructureId()) {
7432
7433 return;
7434 }
7435 }
7436
7437 throw new InvalidDDMStructureException(
7438 "Invalid structure " + ddmStructure.getStructureId() +
7439 " for folder " + folderId);
7440 }
7441
7442 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
7443 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
7444
7445 private static Log _log = LogFactoryUtil.getLog(
7446 JournalArticleLocalServiceImpl.class);
7447
7448 private Date _previousCheckDate;
7449
7450 }