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