001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.NoSuchImageException;
019 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
020 import com.liferay.portal.kernel.dao.orm.QueryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.json.JSONFactoryUtil;
024 import com.liferay.portal.kernel.json.JSONObject;
025 import com.liferay.portal.kernel.language.LanguageUtil;
026 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
027 import com.liferay.portal.kernel.log.Log;
028 import com.liferay.portal.kernel.log.LogFactoryUtil;
029 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
030 import com.liferay.portal.kernel.search.Field;
031 import com.liferay.portal.kernel.search.Hits;
032 import com.liferay.portal.kernel.search.Indexable;
033 import com.liferay.portal.kernel.search.IndexableType;
034 import com.liferay.portal.kernel.search.Indexer;
035 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
036 import com.liferay.portal.kernel.search.QueryConfig;
037 import com.liferay.portal.kernel.search.SearchContext;
038 import com.liferay.portal.kernel.search.SearchException;
039 import com.liferay.portal.kernel.search.Sort;
040 import com.liferay.portal.kernel.systemevent.SystemEvent;
041 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
042 import com.liferay.portal.kernel.util.ArrayUtil;
043 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
044 import com.liferay.portal.kernel.util.CharPool;
045 import com.liferay.portal.kernel.util.Constants;
046 import com.liferay.portal.kernel.util.ContentTypes;
047 import com.liferay.portal.kernel.util.FileUtil;
048 import com.liferay.portal.kernel.util.GetterUtil;
049 import com.liferay.portal.kernel.util.HtmlUtil;
050 import com.liferay.portal.kernel.util.HttpUtil;
051 import com.liferay.portal.kernel.util.ListUtil;
052 import com.liferay.portal.kernel.util.LocaleUtil;
053 import com.liferay.portal.kernel.util.LocalizationUtil;
054 import com.liferay.portal.kernel.util.MathUtil;
055 import com.liferay.portal.kernel.util.ObjectValuePair;
056 import com.liferay.portal.kernel.util.OrderByComparator;
057 import com.liferay.portal.kernel.util.ParamUtil;
058 import com.liferay.portal.kernel.util.PropsKeys;
059 import com.liferay.portal.kernel.util.StringPool;
060 import com.liferay.portal.kernel.util.StringUtil;
061 import com.liferay.portal.kernel.util.Time;
062 import com.liferay.portal.kernel.util.UnicodeProperties;
063 import com.liferay.portal.kernel.util.Validator;
064 import com.liferay.portal.kernel.workflow.WorkflowConstants;
065 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
066 import com.liferay.portal.kernel.xml.Document;
067 import com.liferay.portal.kernel.xml.DocumentException;
068 import com.liferay.portal.kernel.xml.Element;
069 import com.liferay.portal.kernel.xml.Node;
070 import com.liferay.portal.kernel.xml.SAXReaderUtil;
071 import com.liferay.portal.kernel.xml.XPath;
072 import com.liferay.portal.model.Company;
073 import com.liferay.portal.model.Group;
074 import com.liferay.portal.model.Image;
075 import com.liferay.portal.model.ResourceConstants;
076 import com.liferay.portal.model.SystemEventConstants;
077 import com.liferay.portal.model.User;
078 import com.liferay.portal.service.ServiceContext;
079 import com.liferay.portal.service.ServiceContextUtil;
080 import com.liferay.portal.servlet.filters.cache.CacheUtil;
081 import com.liferay.portal.theme.ThemeDisplay;
082 import com.liferay.portal.util.PortalUtil;
083 import com.liferay.portal.util.PortletKeys;
084 import com.liferay.portal.util.PrefsPropsUtil;
085 import com.liferay.portal.util.PropsValues;
086 import com.liferay.portal.util.SubscriptionSender;
087 import com.liferay.portal.webserver.WebServerServletTokenUtil;
088 import com.liferay.portlet.asset.model.AssetEntry;
089 import com.liferay.portlet.asset.model.AssetLink;
090 import com.liferay.portlet.asset.model.AssetLinkConstants;
091 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
092 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
093 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
094 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
095 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
096 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
097 import com.liferay.portlet.journal.ArticleContentException;
098 import com.liferay.portlet.journal.ArticleDisplayDateException;
099 import com.liferay.portlet.journal.ArticleExpirationDateException;
100 import com.liferay.portlet.journal.ArticleIdException;
101 import com.liferay.portlet.journal.ArticleReviewDateException;
102 import com.liferay.portlet.journal.ArticleSmallImageNameException;
103 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
104 import com.liferay.portlet.journal.ArticleTitleException;
105 import com.liferay.portlet.journal.ArticleTypeException;
106 import com.liferay.portlet.journal.ArticleVersionException;
107 import com.liferay.portlet.journal.DuplicateArticleIdException;
108 import com.liferay.portlet.journal.NoSuchArticleException;
109 import com.liferay.portlet.journal.StructureXsdException;
110 import com.liferay.portlet.journal.model.JournalArticle;
111 import com.liferay.portlet.journal.model.JournalArticleConstants;
112 import com.liferay.portlet.journal.model.JournalArticleDisplay;
113 import com.liferay.portlet.journal.model.JournalArticleResource;
114 import com.liferay.portlet.journal.model.JournalFolder;
115 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
116 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
117 import com.liferay.portlet.journal.social.JournalActivityKeys;
118 import com.liferay.portlet.journal.util.JournalUtil;
119 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
120 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
121 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
122 import com.liferay.portlet.social.model.SocialActivityConstants;
123 import com.liferay.portlet.trash.model.TrashEntry;
124 import com.liferay.portlet.trash.model.TrashVersion;
125 import com.liferay.portlet.trash.util.TrashUtil;
126
127 import java.io.File;
128 import java.io.IOException;
129 import java.io.Serializable;
130
131 import java.util.ArrayList;
132 import java.util.Calendar;
133 import java.util.Date;
134 import java.util.HashMap;
135 import java.util.HashSet;
136 import java.util.LinkedHashMap;
137 import java.util.List;
138 import java.util.Locale;
139 import java.util.Map;
140 import java.util.Set;
141
142 import javax.portlet.PortletPreferences;
143
144
173 public class JournalArticleLocalServiceImpl
174 extends JournalArticleLocalServiceBaseImpl {
175
176
259 @Override
260 public JournalArticle addArticle(
261 long userId, long groupId, long folderId, long classNameId,
262 long classPK, String articleId, boolean autoArticleId,
263 double version, Map<Locale, String> titleMap,
264 Map<Locale, String> descriptionMap, String content, String type,
265 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
266 int displayDateMonth, int displayDateDay, int displayDateYear,
267 int displayDateHour, int displayDateMinute, int expirationDateMonth,
268 int expirationDateDay, int expirationDateYear,
269 int expirationDateHour, int expirationDateMinute,
270 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
271 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
272 boolean neverReview, boolean indexable, boolean smallImage,
273 String smallImageURL, File smallImageFile,
274 Map<String, byte[]> images, String articleURL,
275 ServiceContext serviceContext)
276 throws PortalException, SystemException {
277
278
279
280 User user = userPersistence.findByPrimaryKey(userId);
281 articleId = articleId.trim().toUpperCase();
282
283 Date displayDate = null;
284 Date expirationDate = null;
285 Date reviewDate = null;
286
287 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
288 displayDate = PortalUtil.getDate(
289 displayDateMonth, displayDateDay, displayDateYear,
290 displayDateHour, displayDateMinute, user.getTimeZone(),
291 ArticleDisplayDateException.class);
292
293 if (!neverExpire) {
294 expirationDate = PortalUtil.getDate(
295 expirationDateMonth, expirationDateDay, expirationDateYear,
296 expirationDateHour, expirationDateMinute,
297 user.getTimeZone(), ArticleExpirationDateException.class);
298 }
299
300 if (!neverReview) {
301 reviewDate = PortalUtil.getDate(
302 reviewDateMonth, reviewDateDay, reviewDateYear,
303 reviewDateHour, reviewDateMinute, user.getTimeZone(),
304 ArticleReviewDateException.class);
305 }
306 }
307
308 byte[] smallImageBytes = null;
309
310 try {
311 smallImageBytes = FileUtil.getBytes(smallImageFile);
312 }
313 catch (IOException ioe) {
314 }
315
316 Date now = new Date();
317
318 validate(
319 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
320 version, titleMap, content, type, ddmStructureKey, ddmTemplateKey,
321 expirationDate, smallImage, smallImageURL, smallImageFile,
322 smallImageBytes);
323
324 if (autoArticleId) {
325 articleId = String.valueOf(counterLocalService.increment());
326 }
327
328 long id = counterLocalService.increment();
329
330 long resourcePrimKey =
331 journalArticleResourceLocalService.getArticleResourcePrimKey(
332 serviceContext.getUuid(), groupId, articleId);
333
334 JournalArticle article = journalArticlePersistence.create(id);
335
336 Locale locale = LocaleUtil.getSiteDefault();
337
338 String defaultLanguageId = ParamUtil.getString(
339 serviceContext, "defaultLanguageId");
340
341 if (Validator.isNull(defaultLanguageId)) {
342 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
343 }
344
345 if (Validator.isNotNull(defaultLanguageId)) {
346 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
347 }
348
349 String title = titleMap.get(locale);
350
351 content = format(
352 user, groupId, articleId, version, false, content, ddmStructureKey,
353 images);
354
355 article.setResourcePrimKey(resourcePrimKey);
356 article.setGroupId(groupId);
357 article.setCompanyId(user.getCompanyId());
358 article.setUserId(user.getUserId());
359 article.setUserName(user.getFullName());
360 article.setCreateDate(serviceContext.getCreateDate(now));
361 article.setModifiedDate(serviceContext.getModifiedDate(now));
362 article.setFolderId(folderId);
363 article.setClassNameId(classNameId);
364 article.setClassPK(classPK);
365 article.setArticleId(articleId);
366 article.setVersion(version);
367 article.setTitleMap(titleMap, locale);
368 article.setUrlTitle(
369 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
370 article.setDescriptionMap(descriptionMap, locale);
371 article.setContent(content);
372 article.setType(type);
373 article.setStructureId(ddmStructureKey);
374 article.setTemplateId(ddmTemplateKey);
375 article.setLayoutUuid(layoutUuid);
376 article.setDisplayDate(displayDate);
377 article.setExpirationDate(expirationDate);
378 article.setReviewDate(reviewDate);
379 article.setIndexable(indexable);
380 article.setSmallImage(smallImage);
381 article.setSmallImageId(counterLocalService.increment());
382 article.setSmallImageURL(smallImageURL);
383
384 if ((expirationDate == null) || expirationDate.after(now)) {
385 article.setStatus(WorkflowConstants.STATUS_DRAFT);
386 }
387 else {
388 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
389 }
390
391 article.setStatusByUserId(userId);
392 article.setStatusDate(serviceContext.getModifiedDate(now));
393 article.setExpandoBridgeAttributes(serviceContext);
394
395 journalArticlePersistence.update(article);
396
397
398
399 if (serviceContext.isAddGroupPermissions() ||
400 serviceContext.isAddGuestPermissions()) {
401
402 addArticleResources(
403 article, serviceContext.isAddGroupPermissions(),
404 serviceContext.isAddGuestPermissions());
405 }
406 else {
407 addArticleResources(
408 article, serviceContext.getGroupPermissions(),
409 serviceContext.getGuestPermissions());
410 }
411
412
413
414 saveImages(
415 smallImage, article.getSmallImageId(), smallImageFile,
416 smallImageBytes);
417
418
419
420 updateAsset(
421 userId, article, serviceContext.getAssetCategoryIds(),
422 serviceContext.getAssetTagNames(),
423 serviceContext.getAssetLinkEntryIds());
424
425
426
427 if (PortalUtil.getClassNameId(DDMStructure.class) == classNameId) {
428 updateDDMStructureXSD(classPK, content, serviceContext);
429 }
430
431
432
433 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
434 mbMessageLocalService.addDiscussionMessage(
435 userId, article.getUserName(), groupId,
436 JournalArticle.class.getName(), resourcePrimKey,
437 WorkflowConstants.ACTION_PUBLISH);
438 }
439
440
441
442 PortletPreferences preferences =
443 ServiceContextUtil.getPortletPreferences(serviceContext);
444
445 sendEmail(
446 article, articleURL, preferences, "requested", serviceContext);
447
448
449
450 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
451 WorkflowHandlerRegistryUtil.startWorkflowInstance(
452 user.getCompanyId(), groupId, userId,
453 JournalArticle.class.getName(), article.getId(), article,
454 serviceContext);
455
456 if (serviceContext.getWorkflowAction() !=
457 WorkflowConstants.ACTION_PUBLISH) {
458
459
460
461 reindex(article);
462 }
463 }
464 else {
465 updateStatus(
466 userId, article, WorkflowConstants.STATUS_APPROVED, null,
467 new HashMap<String, Serializable>(), serviceContext);
468 }
469
470 return journalArticlePersistence.findByPrimaryKey(article.getId());
471 }
472
473
502 @Override
503 public JournalArticle addArticle(
504 long userId, long groupId, long folderId,
505 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
506 String content, String ddmStructureKey, String ddmTemplateKey,
507 ServiceContext serviceContext)
508 throws PortalException, SystemException {
509
510 Calendar calendar = CalendarFactoryUtil.getCalendar();
511
512 int displayDateMonth = calendar.get(Calendar.MONTH);
513 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
514 int displayDateYear = calendar.get(Calendar.YEAR);
515 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
516 int displayDateMinute = calendar.get(Calendar.MINUTE);
517
518 return addArticle(
519 userId, groupId, folderId,
520 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
521 true, 1, titleMap, descriptionMap, content, "general",
522 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
523 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
524 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
525 null, null, serviceContext);
526 }
527
528
538 @Override
539 public void addArticleResources(
540 JournalArticle article, boolean addGroupPermissions,
541 boolean addGuestPermissions)
542 throws PortalException, SystemException {
543
544 resourceLocalService.addResources(
545 article.getCompanyId(), article.getGroupId(), article.getUserId(),
546 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
547 addGroupPermissions, addGuestPermissions);
548 }
549
550
559 @Override
560 public void addArticleResources(
561 JournalArticle article, String[] groupPermissions,
562 String[] guestPermissions)
563 throws PortalException, SystemException {
564
565 resourceLocalService.addModelResources(
566 article.getCompanyId(), article.getGroupId(), article.getUserId(),
567 JournalArticle.class.getName(), article.getResourcePrimKey(),
568 groupPermissions, guestPermissions);
569 }
570
571
581 @Override
582 public void addArticleResources(
583 long groupId, String articleId, boolean addGroupPermissions,
584 boolean addGuestPermissions)
585 throws PortalException, SystemException {
586
587 JournalArticle article = getLatestArticle(groupId, articleId);
588
589 addArticleResources(article, addGroupPermissions, addGuestPermissions);
590 }
591
592
603 @Override
604 public void addArticleResources(
605 long groupId, String articleId, String[] groupPermissions,
606 String[] guestPermissions)
607 throws PortalException, SystemException {
608
609 JournalArticle article = getLatestArticle(groupId, articleId);
610
611 addArticleResources(article, groupPermissions, guestPermissions);
612 }
613
614
627 @Override
628 public JournalArticle checkArticleResourcePrimKey(
629 long groupId, String articleId, double version)
630 throws PortalException, SystemException {
631
632 JournalArticle article = journalArticlePersistence.findByG_A_V(
633 groupId, articleId, version);
634
635 if (article.getResourcePrimKey() > 0) {
636 return article;
637 }
638
639 long resourcePrimKey =
640 journalArticleResourceLocalService.getArticleResourcePrimKey(
641 groupId, articleId);
642
643 article.setResourcePrimKey(resourcePrimKey);
644
645 journalArticlePersistence.update(article);
646
647 return article;
648 }
649
650
657 @Override
658 public void checkArticles() throws PortalException, SystemException {
659 Date now = new Date();
660
661 List<JournalArticle> articles =
662 journalArticleFinder.findByExpirationDate(
663 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
664 new Date(now.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
665 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
666
667 if (_log.isDebugEnabled()) {
668 _log.debug("Expiring " + articles.size() + " articles");
669 }
670
671 Set<Long> companyIds = new HashSet<Long>();
672
673 for (JournalArticle article : articles) {
674 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
675 List<JournalArticle> currentArticles =
676 journalArticlePersistence.findByG_A(
677 article.getGroupId(), article.getArticleId(),
678 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
679 new ArticleVersionComparator(true));
680
681 for (JournalArticle currentArticle : currentArticles) {
682 currentArticle.setExpirationDate(
683 article.getExpirationDate());
684 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
685
686 journalArticlePersistence.update(currentArticle);
687 }
688 }
689 else {
690 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
691
692 journalArticlePersistence.update(article);
693 }
694
695 updatePreviousApprovedArticle(article);
696
697 JournalContentUtil.clearCache(
698 article.getGroupId(), article.getArticleId(),
699 article.getTemplateId());
700
701 companyIds.add(article.getCompanyId());
702 }
703
704 for (long companyId : companyIds) {
705 CacheUtil.clearCache(companyId);
706 }
707
708 if (_previousCheckDate == null) {
709 _previousCheckDate = new Date(
710 now.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
711 }
712
713 articles = journalArticleFinder.findByReviewDate(
714 JournalArticleConstants.CLASSNAME_ID_DEFAULT, now,
715 _previousCheckDate);
716
717 if (_log.isDebugEnabled()) {
718 _log.debug(
719 "Sending review notifications for " + articles.size() +
720 " articles");
721 }
722
723 for (JournalArticle article : articles) {
724 String articleURL = StringPool.BLANK;
725
726 long ownerId = article.getGroupId();
727 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
728 long plid = PortletKeys.PREFS_PLID_SHARED;
729 String portletId = PortletKeys.JOURNAL;
730
731 PortletPreferences preferences =
732 portletPreferencesLocalService.getPreferences(
733 article.getCompanyId(), ownerId, ownerType, plid,
734 portletId);
735
736 sendEmail(
737 article, articleURL, preferences, "review",
738 new ServiceContext());
739 }
740
741 articles = journalArticlePersistence.findByLtD_S(
742 now, WorkflowConstants.STATUS_SCHEDULED);
743
744 for (JournalArticle article : articles) {
745 ServiceContext serviceContext = new ServiceContext();
746
747 serviceContext.setCommand(Constants.UPDATE);
748
749 String layoutFullURL = PortalUtil.getLayoutFullURL(
750 article.getGroupId(), PortletKeys.JOURNAL);
751
752 serviceContext.setLayoutFullURL(layoutFullURL);
753
754 serviceContext.setScopeGroupId(article.getGroupId());
755
756 updateStatus(
757 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
758 null, new HashMap<String, Serializable>(), serviceContext);
759 }
760
761 _previousCheckDate = now;
762 }
763
764
776 @Override
777 public void checkNewLine(long groupId, String articleId, double version)
778 throws PortalException, SystemException {
779
780 JournalArticle article = journalArticlePersistence.findByG_A_V(
781 groupId, articleId, version);
782
783 String content = GetterUtil.getString(article.getContent());
784
785 if (content.contains("\\n")) {
786 content = StringUtil.replace(
787 content, new String[] {"\\n", "\\r"},
788 new String[] {"\n", "\r"});
789
790 article.setContent(content);
791
792 journalArticlePersistence.update(article);
793 }
794 }
795
796
809 @Override
810 public void checkStructure(long groupId, String articleId, double version)
811 throws PortalException, SystemException {
812
813 JournalArticle article = journalArticlePersistence.findByG_A_V(
814 groupId, articleId, version);
815
816 if (Validator.isNull(article.getStructureId())) {
817 return;
818 }
819
820 checkStructure(article);
821 }
822
823
839 @Override
840 public JournalArticle copyArticle(
841 long userId, long groupId, String oldArticleId, String newArticleId,
842 boolean autoArticleId, double version)
843 throws PortalException, SystemException {
844
845
846
847 User user = userPersistence.findByPrimaryKey(userId);
848 oldArticleId = oldArticleId.trim().toUpperCase();
849 newArticleId = newArticleId.trim().toUpperCase();
850 Date now = new Date();
851
852 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
853 groupId, oldArticleId, version);
854
855 if (autoArticleId) {
856 newArticleId = String.valueOf(counterLocalService.increment());
857 }
858 else {
859 validate(newArticleId);
860
861 if (journalArticlePersistence.countByG_A(
862 groupId, newArticleId) > 0) {
863
864 throw new DuplicateArticleIdException();
865 }
866 }
867
868 long id = counterLocalService.increment();
869
870 long resourcePrimKey =
871 journalArticleResourceLocalService.getArticleResourcePrimKey(
872 groupId, newArticleId);
873
874 JournalArticle newArticle = journalArticlePersistence.create(id);
875
876 newArticle.setResourcePrimKey(resourcePrimKey);
877 newArticle.setGroupId(groupId);
878 newArticle.setCompanyId(user.getCompanyId());
879 newArticle.setUserId(user.getUserId());
880 newArticle.setUserName(user.getFullName());
881 newArticle.setCreateDate(now);
882 newArticle.setModifiedDate(now);
883 newArticle.setFolderId(oldArticle.getFolderId());
884 newArticle.setArticleId(newArticleId);
885 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
886 newArticle.setTitle(oldArticle.getTitle());
887 newArticle.setUrlTitle(
888 getUniqueUrlTitle(
889 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
890 newArticle.setDescription(oldArticle.getDescription());
891
892 try {
893 copyArticleImages(oldArticle, newArticle);
894 }
895 catch (Exception e) {
896 newArticle.setContent(oldArticle.getContent());
897 }
898
899 newArticle.setType(oldArticle.getType());
900 newArticle.setStructureId(oldArticle.getStructureId());
901 newArticle.setTemplateId(oldArticle.getTemplateId());
902 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
903 newArticle.setDisplayDate(oldArticle.getDisplayDate());
904 newArticle.setExpirationDate(oldArticle.getExpirationDate());
905 newArticle.setReviewDate(oldArticle.getReviewDate());
906 newArticle.setIndexable(oldArticle.isIndexable());
907 newArticle.setSmallImage(oldArticle.isSmallImage());
908 newArticle.setSmallImageId(counterLocalService.increment());
909 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
910
911 if (oldArticle.isPending() ||
912 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
913 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
914
915 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
916 }
917 else {
918 newArticle.setStatus(oldArticle.getStatus());
919 }
920
921 newArticle.setExpandoBridgeAttributes(oldArticle);
922
923 journalArticlePersistence.update(newArticle);
924
925
926
927 addArticleResources(newArticle, true, true);
928
929
930
931 if (oldArticle.getSmallImage()) {
932 Image image = imageLocalService.getImage(
933 oldArticle.getSmallImageId());
934
935 byte[] smallImageBytes = image.getTextObj();
936
937 imageLocalService.updateImage(
938 newArticle.getSmallImageId(), smallImageBytes);
939 }
940
941
942
943 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
944 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
945 String[] assetTagNames = assetTagLocalService.getTagNames(
946 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
947
948 updateAsset(userId, newArticle, assetCategoryIds, assetTagNames, null);
949
950 return newArticle;
951 }
952
953
960 @Override
961 @SystemEvent(
962 action = SystemEventConstants.ACTION_SKIP, send = false)
963 public void deleteArticle(JournalArticle article)
964 throws PortalException, SystemException {
965
966 deleteArticle(article, StringPool.BLANK, null);
967 }
968
969
983 @Override
984 @SystemEvent(
985 action = SystemEventConstants.ACTION_SKIP, send = false)
986 public void deleteArticle(
987 JournalArticle article, String articleURL,
988 ServiceContext serviceContext)
989 throws PortalException, SystemException {
990
991 JournalArticleResource articleResource =
992 journalArticleResourceLocalService.fetchArticleResource(
993 article.getGroupId(), article.getArticleId());
994
995 if (article.isApproved() &&
996 isLatestVersion(
997 article.getGroupId(), article.getArticleId(),
998 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
999
1000 updatePreviousApprovedArticle(article);
1001 }
1002 else if (article.isInTrash()) {
1003 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1004 JournalArticle.class);
1005
1006 indexer.delete(article);
1007 }
1008
1009
1010
1011 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
1012 PortletPreferences preferences =
1013 ServiceContextUtil.getPortletPreferences(serviceContext);
1014
1015 if ((preferences != null) && !article.isApproved() &&
1016 isLatestVersion(
1017 article.getGroupId(), article.getArticleId(),
1018 article.getVersion())) {
1019
1020 sendEmail(
1021 article, articleURL, preferences, "denied", serviceContext);
1022 }
1023 }
1024
1025
1026
1027 journalArticleImageLocalService.deleteImages(
1028 article.getGroupId(), article.getArticleId(), article.getVersion());
1029
1030
1031
1032 expandoRowLocalService.deleteRows(article.getId());
1033
1034
1035
1036 if (!article.isDraft()) {
1037 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
1038 article.getCompanyId(), article.getGroupId(),
1039 JournalArticle.class.getName(), article.getId());
1040 }
1041
1042 int articlesCount = journalArticlePersistence.countByG_A(
1043 article.getGroupId(), article.getArticleId());
1044
1045 if (articlesCount == 1) {
1046
1047
1048
1049 subscriptionLocalService.deleteSubscriptions(
1050 article.getCompanyId(), JournalArticle.class.getName(),
1051 article.getResourcePrimKey());
1052
1053
1054
1055 ratingsStatsLocalService.deleteStats(
1056 JournalArticle.class.getName(), article.getResourcePrimKey());
1057
1058
1059
1060 mbMessageLocalService.deleteDiscussionMessages(
1061 JournalArticle.class.getName(), article.getResourcePrimKey());
1062
1063
1064
1065 assetEntryLocalService.deleteEntry(
1066 JournalArticle.class.getName(), article.getResourcePrimKey());
1067
1068
1069
1070 journalContentSearchLocalService.deleteArticleContentSearches(
1071 article.getGroupId(), article.getArticleId());
1072
1073
1074
1075 imageLocalService.deleteImage(article.getSmallImageId());
1076
1077
1078
1079 trashEntryLocalService.deleteEntry(
1080 JournalArticle.class.getName(), article.getResourcePrimKey());
1081
1082
1083
1084 resourceLocalService.deleteResource(
1085 article.getCompanyId(), JournalArticle.class.getName(),
1086 ResourceConstants.SCOPE_INDIVIDUAL,
1087 article.getResourcePrimKey());
1088
1089
1090
1091 if (articleResource != null) {
1092 journalArticleResourceLocalService.deleteJournalArticleResource(
1093 articleResource);
1094 }
1095 }
1096
1097
1098
1099 journalArticlePersistence.remove(article);
1100
1101
1102
1103 if (articleResource != null) {
1104 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1105
1106 extraDataJSONObject.put("version", article.getVersion());
1107
1108 systemEventLocalService.addSystemEvent(
1109 0, article.getGroupId(), article.getModelClassName(),
1110 article.getPrimaryKey(), articleResource.getUuid(), null,
1111 SystemEventConstants.TYPE_DELETE,
1112 extraDataJSONObject.toString());
1113 }
1114 }
1115
1116
1132 @Override
1133 public void deleteArticle(
1134 long groupId, String articleId, double version, String articleURL,
1135 ServiceContext serviceContext)
1136 throws PortalException, SystemException {
1137
1138 JournalArticle article = journalArticlePersistence.findByG_A_V(
1139 groupId, articleId, version);
1140
1141 journalArticleLocalService.deleteArticle(
1142 article, articleURL, serviceContext);
1143 }
1144
1145
1158 @Override
1159 public void deleteArticle(
1160 long groupId, String articleId, ServiceContext serviceContext)
1161 throws PortalException, SystemException {
1162
1163 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class, 0);
1164
1165 JournalArticleResource articleResource =
1166 journalArticleResourceLocalService.fetchArticleResource(
1167 groupId, articleId);
1168
1169 try {
1170 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1171 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1172 new ArticleVersionComparator(true));
1173
1174 for (JournalArticle article : articles) {
1175 deleteArticle(article, null, serviceContext);
1176 }
1177 }
1178 finally {
1179 SystemEventHierarchyEntryThreadLocal.pop();
1180 }
1181
1182 if (articleResource != null) {
1183 systemEventLocalService.addSystemEvent(
1184 0, groupId, JournalArticle.class.getName(),
1185 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1186 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1187 }
1188 }
1189
1190
1197 @Override
1198 public void deleteArticles(long groupId)
1199 throws PortalException, SystemException {
1200
1201 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class, 0);
1202
1203 List<JournalArticleResource> articleResources =
1204 new ArrayList<JournalArticleResource>();
1205
1206 try {
1207 JournalArticleResource articleResource = null;
1208
1209 for (JournalArticle article :
1210 journalArticlePersistence.findByGroupId(groupId)) {
1211
1212 if ((articleResource == null) ||
1213 (articleResource.getPrimaryKey() !=
1214 article.getResourcePrimKey())) {
1215
1216 articleResource =
1217 journalArticleResourceLocalService.getArticleResource(
1218 article.getResourcePrimKey());
1219
1220 articleResources.add(articleResource);
1221 }
1222
1223 deleteArticle(article, null, null);
1224 }
1225 }
1226 finally {
1227 SystemEventHierarchyEntryThreadLocal.pop();
1228 }
1229
1230 for (JournalArticleResource articleResource : articleResources) {
1231 systemEventLocalService.addSystemEvent(
1232 0, groupId, JournalArticle.class.getName(),
1233 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1234 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1235 }
1236 }
1237
1238
1247 @Override
1248 public void deleteArticles(long groupId, long folderId)
1249 throws PortalException, SystemException {
1250
1251 deleteArticles(groupId, folderId, true);
1252 }
1253
1254
1265 @Override
1266 public void deleteArticles(
1267 long groupId, long folderId, boolean includeTrashedEntries)
1268 throws PortalException, SystemException {
1269
1270 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class, 0);
1271
1272 List<JournalArticleResource> articleResources =
1273 new ArrayList<JournalArticleResource>();
1274
1275 try {
1276 JournalArticleResource articleResource = null;
1277
1278 for (JournalArticle article :
1279 journalArticlePersistence.findByG_F(groupId, folderId)) {
1280
1281 if ((articleResource == null) ||
1282 (articleResource.getPrimaryKey() !=
1283 article.getResourcePrimKey())) {
1284
1285 articleResource =
1286 journalArticleResourceLocalService.getArticleResource(
1287 article.getResourcePrimKey());
1288
1289 articleResources.add(articleResource);
1290 }
1291
1292 if (includeTrashedEntries || !article.isInTrash()) {
1293 deleteArticle(article, null, null);
1294 }
1295 else {
1296 articleResources.remove(articleResource);
1297 }
1298 }
1299 }
1300 finally {
1301 SystemEventHierarchyEntryThreadLocal.pop();
1302 }
1303
1304 for (JournalArticleResource articleResource : articleResources) {
1305 systemEventLocalService.addSystemEvent(
1306 0, groupId, JournalArticle.class.getName(),
1307 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1308 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1309 }
1310 }
1311
1312
1321 @Override
1322 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
1323 throws SystemException {
1324
1325 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1326 groupId, layoutUuid);
1327
1328 for (JournalArticle article : articles) {
1329 article.setLayoutUuid(StringPool.BLANK);
1330
1331 journalArticlePersistence.update(article);
1332 }
1333 }
1334
1335
1358 @Override
1359 public JournalArticle expireArticle(
1360 long userId, long groupId, String articleId, double version,
1361 String articleURL, ServiceContext serviceContext)
1362 throws PortalException, SystemException {
1363
1364 return updateStatus(
1365 userId, groupId, articleId, version,
1366 WorkflowConstants.STATUS_EXPIRED, articleURL,
1367 new HashMap<String, Serializable>(), serviceContext);
1368 }
1369
1370
1393 @Override
1394 public void expireArticle(
1395 long userId, long groupId, String articleId, String articleURL,
1396 ServiceContext serviceContext)
1397 throws PortalException, SystemException {
1398
1399 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1400 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1401 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1402 new ArticleVersionComparator(true));
1403
1404 for (JournalArticle article : articles) {
1405 expireArticle(
1406 userId, groupId, article.getArticleId(),
1407 article.getVersion(), articleURL, serviceContext);
1408 }
1409 }
1410 else {
1411 JournalArticle article = getLatestArticle(
1412 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1413
1414 expireArticle(
1415 userId, groupId, article.getArticleId(), article.getVersion(),
1416 articleURL, serviceContext);
1417 }
1418 }
1419
1420 @Override
1421 public JournalArticle fetchArticle(
1422 long groupId, String articleId, double version)
1423 throws SystemException {
1424
1425 return journalArticlePersistence.fetchByG_A_V(
1426 groupId, articleId, version);
1427 }
1428
1429 @Override
1430 public JournalArticle fetchLatestArticle(
1431 long resourcePrimKey, int status, boolean preferApproved)
1432 throws SystemException {
1433
1434 JournalArticle article = null;
1435
1436 OrderByComparator orderByComparator = new ArticleVersionComparator();
1437
1438 if (status == WorkflowConstants.STATUS_ANY) {
1439 if (preferApproved) {
1440 article = journalArticlePersistence.fetchByR_ST_First(
1441 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1442 orderByComparator);
1443 }
1444
1445 if (article == null) {
1446 article =
1447 journalArticlePersistence.fetchByResourcePrimKey_First(
1448 resourcePrimKey, orderByComparator);
1449 }
1450 }
1451 else {
1452 article = journalArticlePersistence.fetchByR_ST_First(
1453 resourcePrimKey, status, orderByComparator);
1454 }
1455
1456 return article;
1457 }
1458
1459 @Override
1460 public JournalArticle fetchLatestArticle(
1461 long groupId, String articleId, int status)
1462 throws SystemException {
1463
1464 OrderByComparator orderByComparator = new ArticleVersionComparator();
1465
1466 if (status == WorkflowConstants.STATUS_ANY) {
1467 return journalArticlePersistence.fetchByG_A_First(
1468 groupId, articleId, orderByComparator);
1469 }
1470
1471 return journalArticlePersistence.fetchByG_A_ST_First(
1472 groupId, articleId, status, orderByComparator);
1473 }
1474
1475 @Override
1476 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey)
1477 throws SystemException {
1478
1479 OrderByComparator orderByComparator = new ArticleVersionComparator();
1480
1481 int[] statuses = new int[] {
1482 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1483 };
1484
1485 List<JournalArticle> articles =
1486 journalArticlePersistence.findByR_I_S(
1487 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1488
1489 if (articles.isEmpty()) {
1490 return null;
1491 }
1492
1493 return articles.get(0);
1494 }
1495
1496
1505 @Override
1506 public JournalArticle getArticle(long id)
1507 throws PortalException, SystemException {
1508
1509 return journalArticlePersistence.findByPrimaryKey(id);
1510 }
1511
1512
1524 @Override
1525 public JournalArticle getArticle(long groupId, String articleId)
1526 throws PortalException, SystemException {
1527
1528
1529
1530
1531 try {
1532 return getLatestArticle(
1533 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1534 }
1535 catch (NoSuchArticleException nsae) {
1536 return getLatestArticle(
1537 groupId, articleId, WorkflowConstants.STATUS_ANY);
1538 }
1539 }
1540
1541
1553 @Override
1554 public JournalArticle getArticle(
1555 long groupId, String articleId, double version)
1556 throws PortalException, SystemException {
1557
1558 return journalArticlePersistence.findByG_A_V(
1559 groupId, articleId, version);
1560 }
1561
1562
1580 @Override
1581 public JournalArticle getArticle(
1582 long groupId, String className, long classPK)
1583 throws PortalException, SystemException {
1584
1585 long classNameId = PortalUtil.getClassNameId(className);
1586
1587 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1588 groupId, classNameId, classPK);
1589
1590 if (articles.isEmpty()) {
1591 throw new NoSuchArticleException(
1592 "No approved JournalArticle exists with the key {groupId=" +
1593 groupId + ", className=" + className + ", classPK=" +
1594 classPK + "}");
1595 }
1596
1597 return articles.get(0);
1598 }
1599
1600
1611 @Override
1612 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1613 throws PortalException, SystemException {
1614
1615
1616
1617
1618 try {
1619 return getLatestArticleByUrlTitle(
1620 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1621 }
1622 catch (NoSuchArticleException nsae) {
1623 return getLatestArticleByUrlTitle(
1624 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1625 }
1626 }
1627
1628
1645 @Override
1646 public String getArticleContent(
1647 JournalArticle article, String ddmTemplateKey, String viewMode,
1648 String languageId, ThemeDisplay themeDisplay)
1649 throws PortalException, SystemException {
1650
1651 JournalArticleDisplay articleDisplay = getArticleDisplay(
1652 article, ddmTemplateKey, viewMode, languageId, 1, null,
1653 themeDisplay);
1654
1655 if (articleDisplay == null) {
1656 return StringPool.BLANK;
1657 }
1658 else {
1659 return articleDisplay.getContent();
1660 }
1661 }
1662
1663
1682 @Override
1683 public String getArticleContent(
1684 long groupId, String articleId, double version, String viewMode,
1685 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1686 throws PortalException, SystemException {
1687
1688 JournalArticleDisplay articleDisplay = getArticleDisplay(
1689 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1690 themeDisplay);
1691
1692 if (articleDisplay == null) {
1693 return StringPool.BLANK;
1694 }
1695 else {
1696 return articleDisplay.getContent();
1697 }
1698 }
1699
1700
1714 @Override
1715 public String getArticleContent(
1716 long groupId, String articleId, double version, String viewMode,
1717 String languageId, ThemeDisplay themeDisplay)
1718 throws PortalException, SystemException {
1719
1720 return getArticleContent(
1721 groupId, articleId, version, viewMode, null, languageId,
1722 themeDisplay);
1723 }
1724
1725
1743 @Override
1744 public String getArticleContent(
1745 long groupId, String articleId, String viewMode,
1746 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1747 throws PortalException, SystemException {
1748
1749 JournalArticleDisplay articleDisplay = getArticleDisplay(
1750 groupId, articleId, ddmTemplateKey, viewMode, languageId,
1751 themeDisplay);
1752
1753 return articleDisplay.getContent();
1754 }
1755
1756
1769 @Override
1770 public String getArticleContent(
1771 long groupId, String articleId, String viewMode, String languageId,
1772 ThemeDisplay themeDisplay)
1773 throws PortalException, SystemException {
1774
1775 return getArticleContent(
1776 groupId, articleId, viewMode, null, languageId, themeDisplay);
1777 }
1778
1779
1803 @Override
1804 public JournalArticleDisplay getArticleDisplay(
1805 JournalArticle article, String ddmTemplateKey, String viewMode,
1806 String languageId, int page, String xmlRequest,
1807 ThemeDisplay themeDisplay)
1808 throws PortalException, SystemException {
1809
1810 String content = null;
1811
1812 if (page < 1) {
1813 page = 1;
1814 }
1815
1816 int numberOfPages = 1;
1817 boolean paginate = false;
1818 boolean pageFlow = false;
1819
1820 boolean cacheable = true;
1821
1822 if (Validator.isNull(xmlRequest)) {
1823 xmlRequest = "<request />";
1824 }
1825
1826 Map<String, String> tokens = JournalUtil.getTokens(
1827 article.getGroupId(), themeDisplay, xmlRequest);
1828
1829 if ((themeDisplay == null) && xmlRequest.equals("<request />")) {
1830 tokens.put("company_id", String.valueOf(article.getCompanyId()));
1831
1832 Group companyGroup = groupLocalService.getCompanyGroup(
1833 article.getCompanyId());
1834
1835 tokens.put(
1836 "article_group_id", String.valueOf(article.getGroupId()));
1837 tokens.put(
1838 "company_group_id", String.valueOf(companyGroup.getGroupId()));
1839
1840
1841
1842 tokens.put("group_id", String.valueOf(article.getGroupId()));
1843 }
1844
1845 tokens.put(
1846 "article_resource_pk",
1847 String.valueOf(article.getResourcePrimKey()));
1848
1849 String defaultDDMTemplateKey = article.getTemplateId();
1850
1851 if (article.isTemplateDriven()) {
1852 if (Validator.isNull(ddmTemplateKey)) {
1853 ddmTemplateKey = defaultDDMTemplateKey;
1854 }
1855
1856 tokens.put("structure_id", article.getStructureId());
1857 tokens.put("template_id", ddmTemplateKey);
1858 }
1859
1860 String xml = article.getContent();
1861
1862 try {
1863 Document document = null;
1864
1865 Element rootElement = null;
1866
1867 if (article.isTemplateDriven()) {
1868 document = SAXReaderUtil.read(xml);
1869
1870 rootElement = document.getRootElement();
1871
1872 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1873
1874 List<Element> pages = rootElement.elements("page");
1875
1876 if (!pages.isEmpty()) {
1877 pageFlow = true;
1878
1879 String targetPage = requestDocument.valueOf(
1880 "/request/parameters/parameter[name='targetPage']/" +
1881 "value");
1882
1883 Element pageElement = null;
1884
1885 if (Validator.isNotNull(targetPage)) {
1886 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
1887
1888 XPath xPathSelector = SAXReaderUtil.createXPath(
1889 "/root/page[@id = " + targetPage + "]");
1890
1891 pageElement = (Element)xPathSelector.selectSingleNode(
1892 document);
1893 }
1894
1895 if (pageElement != null) {
1896 document = SAXReaderUtil.createDocument(pageElement);
1897
1898 rootElement = document.getRootElement();
1899
1900 numberOfPages = pages.size();
1901 }
1902 else {
1903 if (page > pages.size()) {
1904 page = 1;
1905 }
1906
1907 pageElement = pages.get(page - 1);
1908
1909 document = SAXReaderUtil.createDocument(pageElement);
1910
1911 rootElement = document.getRootElement();
1912
1913 numberOfPages = pages.size();
1914 paginate = true;
1915 }
1916 }
1917
1918 rootElement.add(requestDocument.getRootElement().createCopy());
1919
1920 JournalUtil.addAllReservedEls(
1921 rootElement, tokens, article, languageId, themeDisplay);
1922
1923 xml = DDMXMLUtil.formatXML(document);
1924 }
1925 }
1926 catch (DocumentException de) {
1927 throw new SystemException(de);
1928 }
1929
1930 try {
1931 if (_log.isDebugEnabled()) {
1932 _log.debug(
1933 "Transforming " + article.getArticleId() + " " +
1934 article.getVersion() + " " + languageId);
1935 }
1936
1937 String script = null;
1938 String langType = null;
1939
1940 if (article.isTemplateDriven()) {
1941
1942
1943
1944
1945
1946
1947
1948 DDMTemplate ddmTemplate = null;
1949
1950 try {
1951 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1952 article.getGroupId(),
1953 PortalUtil.getClassNameId(DDMStructure.class),
1954 ddmTemplateKey);
1955 }
1956 catch (NoSuchTemplateException nste1) {
1957 try {
1958 Group companyGroup = groupLocalService.getCompanyGroup(
1959 article.getCompanyId());
1960
1961 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1962 companyGroup.getGroupId(),
1963 PortalUtil.getClassNameId(DDMStructure.class),
1964 ddmTemplateKey);
1965
1966 tokens.put(
1967 "company_group_id",
1968 String.valueOf(companyGroup.getGroupId()));
1969 }
1970 catch (NoSuchTemplateException nste2) {
1971 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
1972 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1973 article.getGroupId(),
1974 PortalUtil.getClassNameId(DDMStructure.class),
1975 defaultDDMTemplateKey);
1976 }
1977 else {
1978 throw nste1;
1979 }
1980 }
1981 }
1982
1983 script = ddmTemplate.getScript();
1984 langType = ddmTemplate.getLanguage();
1985 cacheable = ddmTemplate.isCacheable();
1986 }
1987
1988 content = JournalUtil.transform(
1989 themeDisplay, tokens, viewMode, languageId, xml, script,
1990 langType);
1991
1992 if (!pageFlow) {
1993 String[] pieces = StringUtil.split(
1994 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1995
1996 if (pieces.length > 1) {
1997 if (page > pieces.length) {
1998 page = 1;
1999 }
2000
2001 content = pieces[page - 1];
2002 numberOfPages = pieces.length;
2003 paginate = true;
2004 }
2005 }
2006 }
2007 catch (Exception e) {
2008 throw new SystemException(e);
2009 }
2010
2011 return new JournalArticleDisplayImpl(
2012 article.getCompanyId(), article.getId(),
2013 article.getResourcePrimKey(), article.getGroupId(),
2014 article.getUserId(), article.getArticleId(), article.getVersion(),
2015 article.getTitle(languageId), article.getUrlTitle(),
2016 article.getDescription(languageId),
2017 article.getAvailableLanguageIds(), content, article.getType(),
2018 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
2019 article.getSmallImageId(), article.getSmallImageURL(),
2020 numberOfPages, page, paginate, cacheable);
2021 }
2022
2023
2050 @Override
2051 public JournalArticleDisplay getArticleDisplay(
2052 long groupId, String articleId, double version,
2053 String ddmTemplateKey, String viewMode, String languageId, int page,
2054 String xmlRequest, ThemeDisplay themeDisplay)
2055 throws PortalException, SystemException {
2056
2057 Date now = new Date();
2058
2059 JournalArticle article = journalArticlePersistence.findByG_A_V(
2060 groupId, articleId, version);
2061
2062 if (article.isExpired()) {
2063 Date expirationDate = article.getExpirationDate();
2064
2065 if ((expirationDate != null) && expirationDate.before(now)) {
2066 return null;
2067 }
2068 }
2069
2070 Date displayDate = article.getDisplayDate();
2071
2072 if (displayDate.after(now)) {
2073 return null;
2074 }
2075
2076 return getArticleDisplay(
2077 article, ddmTemplateKey, viewMode, languageId, page, xmlRequest,
2078 themeDisplay);
2079 }
2080
2081
2105 @Override
2106 public JournalArticleDisplay getArticleDisplay(
2107 long groupId, String articleId, double version,
2108 String ddmTemplateKey, String viewMode, String languageId,
2109 ThemeDisplay themeDisplay)
2110 throws PortalException, SystemException {
2111
2112 return getArticleDisplay(
2113 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2114 1, null, themeDisplay);
2115 }
2116
2117
2139 @Override
2140 public JournalArticleDisplay getArticleDisplay(
2141 long groupId, String articleId, String viewMode, String languageId,
2142 int page, String xmlRequest, ThemeDisplay themeDisplay)
2143 throws PortalException, SystemException {
2144
2145 return getArticleDisplay(
2146 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
2147 themeDisplay);
2148 }
2149
2150
2177 @Override
2178 public JournalArticleDisplay getArticleDisplay(
2179 long groupId, String articleId, String ddmTemplateKey,
2180 String viewMode, String languageId, int page, String xmlRequest,
2181 ThemeDisplay themeDisplay)
2182 throws PortalException, SystemException {
2183
2184 JournalArticle article = getDisplayArticle(groupId, articleId);
2185
2186 return getArticleDisplay(
2187 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2188 languageId, page, xmlRequest, themeDisplay);
2189 }
2190
2191
2214 @Override
2215 public JournalArticleDisplay getArticleDisplay(
2216 long groupId, String articleId, String ddmTemplateKey,
2217 String viewMode, String languageId, ThemeDisplay themeDisplay)
2218 throws PortalException, SystemException {
2219
2220 JournalArticle article = getDisplayArticle(groupId, articleId);
2221
2222 return getArticleDisplay(
2223 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2224 languageId, themeDisplay);
2225 }
2226
2227
2245 @Override
2246 public JournalArticleDisplay getArticleDisplay(
2247 long groupId, String articleId, String viewMode, String languageId,
2248 ThemeDisplay themeDisplay)
2249 throws PortalException, SystemException {
2250
2251 return getArticleDisplay(
2252 groupId, articleId, null, viewMode, languageId, themeDisplay);
2253 }
2254
2255
2261 @Override
2262 public List<JournalArticle> getArticles() throws SystemException {
2263 return journalArticlePersistence.findAll();
2264 }
2265
2266
2273 @Override
2274 public List<JournalArticle> getArticles(long groupId)
2275 throws SystemException {
2276
2277 return journalArticlePersistence.findByGroupId(groupId);
2278 }
2279
2280
2300 @Override
2301 public List<JournalArticle> getArticles(long groupId, int start, int end)
2302 throws SystemException {
2303
2304 return journalArticlePersistence.findByGroupId(groupId, start, end);
2305 }
2306
2307
2330 @Override
2331 public List<JournalArticle> getArticles(
2332 long groupId, int start, int end, OrderByComparator obc)
2333 throws SystemException {
2334
2335 return journalArticlePersistence.findByGroupId(
2336 groupId, start, end, obc);
2337 }
2338
2339
2347 @Override
2348 public List<JournalArticle> getArticles(long groupId, long folderId)
2349 throws SystemException {
2350
2351 return journalArticlePersistence.findByG_F(groupId, folderId);
2352 }
2353
2354
2376 @Override
2377 public List<JournalArticle> getArticles(
2378 long groupId, long folderId, int start, int end)
2379 throws SystemException {
2380
2381 return journalArticlePersistence.findByG_F(
2382 groupId, folderId, start, end);
2383 }
2384
2385
2410 @Override
2411 public List<JournalArticle> getArticles(
2412 long groupId, long folderId, int start, int end,
2413 OrderByComparator orderByComparator)
2414 throws SystemException {
2415
2416 return journalArticlePersistence.findByG_F(
2417 groupId, folderId, start, end, orderByComparator);
2418 }
2419
2420
2428 @Override
2429 public List<JournalArticle> getArticles(long groupId, String articleId)
2430 throws SystemException {
2431
2432 return journalArticlePersistence.findByG_A(groupId, articleId);
2433 }
2434
2435 @Override
2436 public List<JournalArticle> getArticlesByResourcePrimKey(
2437 long resourcePrimKey)
2438 throws SystemException {
2439
2440 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2441 }
2442
2443
2451 @Override
2452 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
2453 throws SystemException {
2454
2455 return journalArticlePersistence.findBySmallImageId(smallImageId);
2456 }
2457
2458
2465 @Override
2466 public int getArticlesCount(long groupId) throws SystemException {
2467 return journalArticlePersistence.countByGroupId(groupId);
2468 }
2469
2470
2478 @Override
2479 public int getArticlesCount(long groupId, long folderId)
2480 throws SystemException {
2481
2482 return journalArticlePersistence.countByG_F(groupId, folderId);
2483 }
2484
2485
2510 @Override
2511 public List<JournalArticle> getCompanyArticles(
2512 long companyId, double version, int status, int start, int end)
2513 throws SystemException {
2514
2515 if (status == WorkflowConstants.STATUS_ANY) {
2516 return journalArticlePersistence.findByC_V(
2517 companyId, version, start, end, new ArticleIDComparator(true));
2518 }
2519 else {
2520 return journalArticlePersistence.findByC_V_ST(
2521 companyId, version, status, start, end,
2522 new ArticleIDComparator(true));
2523 }
2524 }
2525
2526
2550 @Override
2551 public List<JournalArticle> getCompanyArticles(
2552 long companyId, int status, int start, int end)
2553 throws SystemException {
2554
2555 if (status == WorkflowConstants.STATUS_ANY) {
2556 return journalArticlePersistence.findByCompanyId(
2557 companyId, start, end, new ArticleIDComparator(true));
2558 }
2559 else {
2560 return journalArticlePersistence.findByC_ST(
2561 companyId, status, start, end, new ArticleIDComparator(true));
2562 }
2563 }
2564
2565
2590 @Override
2591 public int getCompanyArticlesCount(
2592 long companyId, double version, int status, int start, int end)
2593 throws SystemException {
2594
2595 if (status == WorkflowConstants.STATUS_ANY) {
2596 return journalArticlePersistence.countByC_V(companyId, version);
2597 }
2598 else {
2599 return journalArticlePersistence.countByC_V_ST(
2600 companyId, version, status);
2601 }
2602 }
2603
2604
2615 @Override
2616 public int getCompanyArticlesCount(long companyId, int status)
2617 throws SystemException {
2618
2619 if (status == WorkflowConstants.STATUS_ANY) {
2620 return journalArticlePersistence.countByCompanyId(companyId);
2621 }
2622 else {
2623 return journalArticlePersistence.countByC_ST(companyId, status);
2624 }
2625 }
2626
2627
2640 @Override
2641 public JournalArticle getDisplayArticle(long groupId, String articleId)
2642 throws PortalException, SystemException {
2643
2644 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2645 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2646
2647 if (articles.isEmpty()) {
2648 throw new NoSuchArticleException(
2649 "No approved JournalArticle exists with the key {groupId=" +
2650 groupId + ", " + "articleId=" + articleId + "}");
2651
2652 }
2653
2654 Date now = new Date();
2655
2656 for (int i = 0; i < articles.size(); i++) {
2657 JournalArticle article = articles.get(i);
2658
2659 Date displayDate = article.getDisplayDate();
2660 Date expirationDate = article.getExpirationDate();
2661
2662 if (((displayDate == null) || displayDate.before(now)) &&
2663 ((expirationDate == null) || expirationDate.after(now))) {
2664
2665 return article;
2666 }
2667 }
2668
2669 return articles.get(0);
2670 }
2671
2672
2685 @Override
2686 public JournalArticle getDisplayArticleByUrlTitle(
2687 long groupId, String urlTitle)
2688 throws PortalException, SystemException {
2689
2690 List<JournalArticle> articles = null;
2691
2692 OrderByComparator orderByComparator = new ArticleVersionComparator();
2693
2694 articles = journalArticlePersistence.findByG_UT_ST(
2695 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2696 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2697
2698 if (articles.isEmpty()) {
2699 throw new NoSuchArticleException(
2700 "No JournalArticle exists with the key {groupId=" + groupId +
2701 ", urlTitle=" + urlTitle + "}");
2702 }
2703
2704 Date now = new Date();
2705
2706 for (JournalArticle article : articles) {
2707 Date displayDate = article.getDisplayDate();
2708 Date expirationDate = article.getExpirationDate();
2709
2710 if (((displayDate != null) && displayDate.before(now)) &&
2711 ((expirationDate == null) || expirationDate.after(now)) ) {
2712
2713 return article;
2714 }
2715 }
2716
2717 return articles.get(0);
2718 }
2719
2720
2731 @Override
2732 public JournalArticle getLatestArticle(long resourcePrimKey)
2733 throws PortalException, SystemException {
2734
2735 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2736 }
2737
2738
2753 @Override
2754 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2755 throws PortalException, SystemException {
2756
2757 return getLatestArticle(resourcePrimKey, status, true);
2758 }
2759
2760
2780 @Override
2781 public JournalArticle getLatestArticle(
2782 long resourcePrimKey, int status, boolean preferApproved)
2783 throws PortalException, SystemException {
2784
2785 List<JournalArticle> articles = null;
2786
2787 OrderByComparator orderByComparator = new ArticleVersionComparator();
2788
2789 if (status == WorkflowConstants.STATUS_ANY) {
2790 if (preferApproved) {
2791 articles = journalArticlePersistence.findByR_ST(
2792 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2793 orderByComparator);
2794 }
2795
2796 if ((articles == null) || (articles.size() == 0)) {
2797 articles = journalArticlePersistence.findByResourcePrimKey(
2798 resourcePrimKey, 0, 1, orderByComparator);
2799 }
2800 }
2801 else {
2802 articles = journalArticlePersistence.findByR_ST(
2803 resourcePrimKey, status, 0, 1, orderByComparator);
2804 }
2805
2806 if (articles.isEmpty()) {
2807 throw new NoSuchArticleException(
2808 "No JournalArticle exists with the key {resourcePrimKey=" +
2809 resourcePrimKey + "}");
2810 }
2811
2812 return articles.get(0);
2813 }
2814
2815
2825 @Override
2826 public JournalArticle getLatestArticle(long groupId, String articleId)
2827 throws PortalException, SystemException {
2828
2829 return getLatestArticle(
2830 groupId, articleId, WorkflowConstants.STATUS_ANY);
2831 }
2832
2833
2847 @Override
2848 public JournalArticle getLatestArticle(
2849 long groupId, String articleId, int status)
2850 throws PortalException, SystemException {
2851
2852 List<JournalArticle> articles = null;
2853
2854 OrderByComparator orderByComparator = new ArticleVersionComparator();
2855
2856 if (status == WorkflowConstants.STATUS_ANY) {
2857 articles = journalArticlePersistence.findByG_A(
2858 groupId, articleId, 0, 1, orderByComparator);
2859 }
2860 else {
2861 articles = journalArticlePersistence.findByG_A_ST(
2862 groupId, articleId, status, 0, 1, orderByComparator);
2863 }
2864
2865 if (articles.isEmpty()) {
2866 throw new NoSuchArticleException(
2867 "No JournalArticle exists with the key {groupId=" + groupId +
2868 ", articleId=" + articleId + ", status=" + status + "}");
2869 }
2870
2871 return articles.get(0);
2872 }
2873
2874
2892 @Override
2893 public JournalArticle getLatestArticle(
2894 long groupId, String className, long classPK)
2895 throws PortalException, SystemException {
2896
2897 long classNameId = PortalUtil.getClassNameId(className);
2898
2899 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2900 groupId, classNameId, classPK, 0, 1,
2901 new ArticleVersionComparator());
2902
2903 if (articles.isEmpty()) {
2904 throw new NoSuchArticleException(
2905 "No JournalArticle exists with the key {groupId=" + groupId +
2906 ", className=" + className + ", classPK =" + classPK + "}");
2907 }
2908
2909 return articles.get(0);
2910 }
2911
2912
2926 @Override
2927 public JournalArticle getLatestArticleByUrlTitle(
2928 long groupId, String urlTitle, int status)
2929 throws PortalException, SystemException {
2930
2931 List<JournalArticle> articles = null;
2932
2933 OrderByComparator orderByComparator = new ArticleVersionComparator();
2934
2935 if (status == WorkflowConstants.STATUS_ANY) {
2936 articles = journalArticlePersistence.findByG_UT(
2937 groupId, urlTitle, 0, 1, orderByComparator);
2938 }
2939 else {
2940 articles = journalArticlePersistence.findByG_UT_ST(
2941 groupId, urlTitle, status, 0, 1, orderByComparator);
2942 }
2943
2944 if (articles.isEmpty()) {
2945 throw new NoSuchArticleException(
2946 "No JournalArticle exists with the key {groupId=" + groupId +
2947 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2948 }
2949
2950 return articles.get(0);
2951 }
2952
2953
2964 @Override
2965 public double getLatestVersion(long groupId, String articleId)
2966 throws PortalException, SystemException {
2967
2968 JournalArticle article = getLatestArticle(groupId, articleId);
2969
2970 return article.getVersion();
2971 }
2972
2973
2987 @Override
2988 public double getLatestVersion(long groupId, String articleId, int status)
2989 throws PortalException, SystemException {
2990
2991 JournalArticle article = getLatestArticle(groupId, articleId, status);
2992
2993 return article.getVersion();
2994 }
2995
2996
3004 @Override
3005 public int getNotInTrashArticlesCount(long groupId, long folderId)
3006 throws SystemException {
3007
3008 QueryDefinition queryDefinition = new QueryDefinition(
3009 WorkflowConstants.STATUS_ANY);
3010
3011 List<Long> folderIds = new ArrayList<Long>();
3012
3013 folderIds.add(folderId);
3014
3015 return journalArticleFinder.countByG_F(
3016 groupId, folderIds, queryDefinition);
3017 }
3018
3019
3029 @Override
3030 public List<JournalArticle> getStructureArticles(
3031 long groupId, String ddmStructureKey)
3032 throws SystemException {
3033
3034 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
3035 }
3036
3037
3062 @Override
3063 public List<JournalArticle> getStructureArticles(
3064 long groupId, String ddmStructureKey, int start, int end,
3065 OrderByComparator obc)
3066 throws SystemException {
3067
3068 return journalArticlePersistence.findByG_S(
3069 groupId, ddmStructureKey, start, end, obc);
3070 }
3071
3072 @Override
3073 public List<JournalArticle> getStructureArticles(String[] ddmStructureKeys)
3074 throws SystemException {
3075
3076 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
3077 }
3078
3079
3089 @Override
3090 public int getStructureArticlesCount(long groupId, String ddmStructureKey)
3091 throws SystemException {
3092
3093 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
3094 }
3095
3096
3107 @Override
3108 public List<JournalArticle> getTemplateArticles(
3109 long groupId, String ddmTemplateKey)
3110 throws SystemException {
3111
3112 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3113 }
3114
3115
3142 @Override
3143 public List<JournalArticle> getTemplateArticles(
3144 long groupId, String ddmTemplateKey, int start, int end,
3145 OrderByComparator obc)
3146 throws SystemException {
3147
3148 return journalArticlePersistence.findByG_T(
3149 groupId, ddmTemplateKey, start, end, obc);
3150 }
3151
3152
3164 @Override
3165 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey)
3166 throws SystemException {
3167
3168 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3169 }
3170
3171 @Override
3172 public String getUniqueUrlTitle(
3173 long groupId, String articleId, String urlTitle)
3174 throws PortalException, SystemException {
3175
3176 for (int i = 1;; i++) {
3177 JournalArticle article = null;
3178
3179 try {
3180 article = getArticleByUrlTitle(groupId, urlTitle);
3181 }
3182 catch (NoSuchArticleException nsae) {
3183 }
3184
3185 if ((article == null) || articleId.equals(article.getArticleId())) {
3186 break;
3187 }
3188 else {
3189 String suffix = StringPool.DASH + i;
3190
3191 String prefix = urlTitle;
3192
3193 if (urlTitle.length() > suffix.length()) {
3194 prefix = urlTitle.substring(
3195 0, urlTitle.length() - suffix.length());
3196 }
3197
3198 urlTitle = prefix + suffix;
3199 }
3200 }
3201
3202 return urlTitle;
3203 }
3204
3205
3214 @Override
3215 public boolean hasArticle(long groupId, String articleId)
3216 throws SystemException {
3217
3218 try {
3219 getArticle(groupId, articleId);
3220
3221 return true;
3222 }
3223 catch (PortalException pe) {
3224 return false;
3225 }
3226 }
3227
3228
3241 @Override
3242 public boolean isLatestVersion(
3243 long groupId, String articleId, double version)
3244 throws PortalException, SystemException {
3245
3246 if (getLatestVersion(groupId, articleId) == version) {
3247 return true;
3248 }
3249 else {
3250 return false;
3251 }
3252 }
3253
3254
3270 @Override
3271 public boolean isLatestVersion(
3272 long groupId, String articleId, double version, int status)
3273 throws PortalException, SystemException {
3274
3275 if (getLatestVersion(groupId, articleId, status) == version) {
3276 return true;
3277 }
3278 else {
3279 return false;
3280 }
3281 }
3282
3283
3296 @Indexable(type = IndexableType.REINDEX)
3297 @Override
3298 public JournalArticle moveArticle(
3299 long groupId, String articleId, long newFolderId)
3300 throws PortalException, SystemException {
3301
3302 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3303 groupId, articleId);
3304
3305 for (JournalArticle article : articles) {
3306 article.setFolderId(newFolderId);
3307
3308 journalArticlePersistence.update(article);
3309 }
3310
3311 return getArticle(groupId, articleId);
3312 }
3313
3314
3337 @Override
3338 public JournalArticle moveArticleFromTrash(
3339 long userId, long groupId, JournalArticle article, long newFolderId,
3340 ServiceContext serviceContext)
3341 throws PortalException, SystemException {
3342
3343 if (article.isInTrash()) {
3344 restoreArticleFromTrash(userId, article);
3345 }
3346 else {
3347 updateStatus(
3348 userId, article, article.getStatus(), null,
3349 new HashMap<String, Serializable>(), serviceContext);
3350 }
3351
3352 return journalArticleLocalService.moveArticle(
3353 groupId, article.getArticleId(), newFolderId);
3354 }
3355
3356
3369 @Override
3370 public JournalArticle moveArticleToTrash(
3371 long userId, JournalArticle article)
3372 throws PortalException, SystemException {
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 Map<String, Serializable> workflowContext =
3390 new HashMap<String, Serializable>();
3391
3392 workflowContext.put("articleVersions", (Serializable)articleVersions);
3393
3394 article = updateStatus(
3395 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3396 workflowContext, new ServiceContext());
3397
3398
3399
3400 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3401 JournalArticle.class);
3402
3403 indexer.delete(article);
3404
3405 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3406 JournalArticle.class.getName(), article.getResourcePrimKey());
3407
3408 String trashArticleId = TrashUtil.getTrashTitle(
3409 trashEntry.getEntryId());
3410
3411 if (!articleVersions.isEmpty()) {
3412 for (JournalArticle curArticleVersion : articleVersions) {
3413 curArticleVersion.setArticleId(trashArticleId);
3414
3415 journalArticlePersistence.update(curArticleVersion);
3416 }
3417 }
3418
3419 JournalArticleResource articleResource =
3420 journalArticleResourcePersistence.fetchByPrimaryKey(
3421 article.getResourcePrimKey());
3422
3423 articleResource.setArticleId(trashArticleId);
3424
3425 journalArticleResourcePersistence.update(articleResource);
3426
3427 article.setArticleId(trashArticleId);
3428
3429 reindex(article);
3430
3431 article = journalArticlePersistence.update(article);
3432
3433 socialActivityCounterLocalService.disableActivityCounters(
3434 JournalFolder.class.getName(), article.getFolderId());
3435
3436 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3437
3438 extraDataJSONObject.put("title", article.getTitle());
3439
3440 socialActivityLocalService.addActivity(
3441 userId, article.getGroupId(), JournalArticle.class.getName(),
3442 article.getResourcePrimKey(),
3443 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3444 extraDataJSONObject.toString(), 0);
3445
3446 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3447 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3448 article.getCompanyId(), article.getGroupId(),
3449 JournalArticle.class.getName(), article.getId());
3450 }
3451
3452 return article;
3453 }
3454
3455
3469 @Override
3470 public JournalArticle moveArticleToTrash(
3471 long userId, long groupId, String articleId)
3472 throws PortalException, SystemException {
3473
3474 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3475 groupId, articleId, 0, 1, new ArticleVersionComparator());
3476
3477 if (!articles.isEmpty()) {
3478 return moveArticleToTrash(userId, articles.get(0));
3479 }
3480
3481 return null;
3482 }
3483
3484
3497 @Override
3498 public JournalArticle removeArticleLocale(
3499 long groupId, String articleId, double version, String languageId)
3500 throws PortalException, SystemException {
3501
3502 JournalArticle article = journalArticlePersistence.findByG_A_V(
3503 groupId, articleId, version);
3504
3505 String title = article.getTitle();
3506
3507 title = LocalizationUtil.removeLocalization(
3508 title, "static-content", languageId, true);
3509
3510 article.setTitle(title);
3511
3512 String description = article.getDescription();
3513
3514 description = LocalizationUtil.removeLocalization(
3515 description, "static-content", languageId, true);
3516
3517 article.setDescription(description);
3518
3519 String content = article.getContent();
3520
3521 if (article.isTemplateDriven()) {
3522 content = JournalUtil.removeArticleLocale(content, languageId);
3523 }
3524 else {
3525 content = LocalizationUtil.removeLocalization(
3526 content, "static-content", languageId, true);
3527 }
3528
3529 article.setContent(content);
3530
3531 journalArticlePersistence.update(article);
3532
3533 return article;
3534 }
3535
3536
3548 @Override
3549 public void restoreArticleFromTrash(long userId, JournalArticle article)
3550 throws PortalException, SystemException {
3551
3552
3553
3554 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3555 JournalArticle.class);
3556
3557 indexer.delete(article);
3558
3559 String trashArticleId = TrashUtil.getOriginalTitle(
3560 article.getArticleId());
3561
3562 List<JournalArticle> articleVersions =
3563 journalArticlePersistence.findByG_A(
3564 article.getGroupId(), article.getArticleId());
3565
3566 if (!articleVersions.isEmpty()) {
3567 for (JournalArticle curArticleVersion : articleVersions) {
3568 curArticleVersion.setArticleId(trashArticleId);
3569
3570 journalArticlePersistence.update(curArticleVersion);
3571 }
3572 }
3573
3574 article.setArticleId(trashArticleId);
3575
3576 journalArticlePersistence.update(article);
3577
3578 JournalArticleResource articleResource =
3579 journalArticleResourcePersistence.fetchByPrimaryKey(
3580 article.getResourcePrimKey());
3581
3582 articleResource.setArticleId(trashArticleId);
3583
3584 journalArticleResourcePersistence.update(articleResource);
3585
3586 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3587 JournalArticle.class.getName(), article.getResourcePrimKey());
3588
3589 Map<String, Serializable> workflowContext =
3590 new HashMap<String, Serializable>();
3591
3592 List<TrashVersion> trashVersions = trashEntryLocalService.getVersions(
3593 trashEntry.getEntryId());
3594
3595 workflowContext.put("trashVersions", (Serializable)trashVersions);
3596
3597 ServiceContext serviceContext = new ServiceContext();
3598
3599 serviceContext.setScopeGroupId(article.getGroupId());
3600
3601 updateStatus(
3602 userId, article, trashEntry.getStatus(), null, workflowContext,
3603 serviceContext);
3604
3605 socialActivityCounterLocalService.enableActivityCounters(
3606 JournalFolder.class.getName(), article.getFolderId());
3607
3608 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3609
3610 extraDataJSONObject.put("title", article.getTitle());
3611
3612 socialActivityLocalService.addActivity(
3613 userId, article.getGroupId(), JournalArticle.class.getName(),
3614 article.getResourcePrimKey(),
3615 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3616 extraDataJSONObject.toString(), 0);
3617 }
3618
3619
3681 @Override
3682 public List<JournalArticle> search(
3683 long companyId, long groupId, List<Long> folderIds,
3684 long classNameId, String keywords, Double version, String type,
3685 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3686 Date displayDateLT, int status, Date reviewDate, int start, int end,
3687 OrderByComparator obc)
3688 throws SystemException {
3689
3690 return journalArticleFinder.findByKeywords(
3691 companyId, groupId, folderIds, classNameId, keywords, version, type,
3692 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3693 status, reviewDate, start, end, obc);
3694 }
3695
3696
3765 @Override
3766 public List<JournalArticle> search(
3767 long companyId, long groupId, List<Long> folderIds,
3768 long classNameId, String articleId, Double version, String title,
3769 String description, String content, String type,
3770 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3771 Date displayDateLT, int status, Date reviewDate,
3772 boolean andOperator, int start, int end, OrderByComparator obc)
3773 throws SystemException {
3774
3775 QueryDefinition queryDefinition = new QueryDefinition(
3776 status, start, end, obc);
3777
3778 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3779 companyId, groupId, folderIds, classNameId, articleId, version,
3780 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3781 displayDateGT, displayDateLT, reviewDate, andOperator,
3782 queryDefinition);
3783 }
3784
3785
3851 @Override
3852 public List<JournalArticle> search(
3853 long companyId, long groupId, List<Long> folderIds,
3854 long classNameId, String articleId, Double version, String title,
3855 String description, String content, String type,
3856 String[] ddmStructureKeys, String[] ddmTemplateKeys,
3857 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
3858 boolean andOperator, int start, int end, OrderByComparator obc)
3859 throws SystemException {
3860
3861 QueryDefinition queryDefinition = new QueryDefinition(
3862 status, start, end, obc);
3863
3864 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3865 companyId, groupId, folderIds, classNameId, articleId, version,
3866 title, description, content, type, ddmStructureKeys,
3867 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3868 andOperator, queryDefinition);
3869 }
3870
3871
3918 @Override
3919 public Hits search(
3920 long companyId, long groupId, List<Long> folderIds,
3921 long classNameId, String ddmStructureKey, String ddmTemplateKey,
3922 String keywords, LinkedHashMap<String, Object> params, int start,
3923 int end, Sort sort)
3924 throws SystemException {
3925
3926 String articleId = null;
3927 String title = null;
3928 String description = null;
3929 String content = null;
3930 boolean andOperator = false;
3931
3932 if (Validator.isNotNull(keywords)) {
3933 articleId = keywords;
3934 title = keywords;
3935 description = keywords;
3936 content = keywords;
3937 }
3938 else {
3939 andOperator = true;
3940 }
3941
3942 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
3943
3944 if (params != null) {
3945 params.put("keywords", keywords);
3946 }
3947
3948 return search(
3949 companyId, groupId, folderIds, classNameId, articleId, title,
3950 description, content, null, status, ddmStructureKey, ddmTemplateKey,
3951 params, andOperator, start, end, sort);
3952 }
3953
3954
4015 @Override
4016 public Hits search(
4017 long companyId, long groupId, List<Long> folderIds,
4018 long classNameId, String articleId, String title,
4019 String description, String content, String type, String status,
4020 String ddmStructureKey, String ddmTemplateKey,
4021 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4022 int end, Sort sort)
4023 throws SystemException {
4024
4025 try {
4026 SearchContext searchContext = new SearchContext();
4027
4028 searchContext.setAndSearch(andSearch);
4029
4030 Map<String, Serializable> attributes =
4031 new HashMap<String, Serializable>();
4032
4033 attributes.put(Field.CLASS_NAME_ID, classNameId);
4034 attributes.put(Field.CONTENT, content);
4035 attributes.put(Field.DESCRIPTION, description);
4036 attributes.put(Field.STATUS, status);
4037 attributes.put(Field.TITLE, title);
4038 attributes.put(Field.TYPE, type);
4039 attributes.put("articleId", articleId);
4040 attributes.put("ddmStructureKey", ddmStructureKey);
4041 attributes.put("ddmTemplateKey", ddmTemplateKey);
4042 attributes.put("params", params);
4043
4044 searchContext.setAttributes(attributes);
4045
4046 searchContext.setCompanyId(companyId);
4047 searchContext.setEnd(end);
4048 searchContext.setFolderIds(folderIds);
4049 searchContext.setGroupIds(new long[] {groupId});
4050 searchContext.setIncludeDiscussions(
4051 GetterUtil.getBoolean(params.get("includeDiscussions")));
4052
4053 if (params != null) {
4054 String keywords = (String)params.remove("keywords");
4055
4056 if (Validator.isNotNull(keywords)) {
4057 searchContext.setKeywords(keywords);
4058 }
4059 }
4060
4061 QueryConfig queryConfig = new QueryConfig();
4062
4063 queryConfig.setHighlightEnabled(false);
4064 queryConfig.setScoreEnabled(false);
4065
4066 searchContext.setQueryConfig(queryConfig);
4067
4068 if (sort != null) {
4069 searchContext.setSorts(sort);
4070 }
4071
4072 searchContext.setStart(start);
4073
4074 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4075 JournalArticle.class);
4076
4077 return indexer.search(searchContext);
4078 }
4079 catch (Exception e) {
4080 throw new SystemException(e);
4081 }
4082 }
4083
4084 @Override
4085 public Hits search(
4086 long groupId, long userId, long creatorUserId, int status,
4087 int start, int end)
4088 throws PortalException, SystemException {
4089
4090 Indexer indexer = IndexerRegistryUtil.getIndexer(
4091 JournalArticle.class.getName());
4092
4093 SearchContext searchContext = new SearchContext();
4094
4095 searchContext.setAttribute(Field.STATUS, status);
4096
4097 searchContext.setAttribute("paginationType", "none");
4098
4099 if (creatorUserId > 0) {
4100 searchContext.setAttribute(
4101 Field.USER_ID, String.valueOf(creatorUserId));
4102 }
4103
4104 Group group = groupLocalService.getGroup(groupId);
4105
4106 searchContext.setCompanyId(group.getCompanyId());
4107
4108 searchContext.setEnd(end);
4109 searchContext.setGroupIds(new long[] {groupId});
4110 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4111 searchContext.setStart(start);
4112 searchContext.setUserId(userId);
4113
4114 return indexer.search(searchContext);
4115 }
4116
4117
4161 @Override
4162 public int searchCount(
4163 long companyId, long groupId, List<Long> folderIds,
4164 long classNameId, String keywords, Double version, String type,
4165 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4166 Date displayDateLT, int status, Date reviewDate)
4167 throws SystemException {
4168
4169 return journalArticleFinder.countByKeywords(
4170 companyId, groupId, folderIds, classNameId, keywords, version, type,
4171 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4172 status, reviewDate);
4173 }
4174
4175
4225 @Override
4226 public int searchCount(
4227 long companyId, long groupId, List<Long> folderIds,
4228 long classNameId, String articleId, Double version, String title,
4229 String description, String content, String type,
4230 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4231 Date displayDateLT, int status, Date reviewDate,
4232 boolean andOperator)
4233 throws SystemException {
4234
4235 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4236 companyId, groupId, folderIds, classNameId, articleId, version,
4237 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4238 displayDateGT, displayDateLT, reviewDate, andOperator,
4239 new QueryDefinition(status));
4240 }
4241
4242
4292 @Override
4293 public int searchCount(
4294 long companyId, long groupId, List<Long> folderIds,
4295 long classNameId, String articleId, Double version, String title,
4296 String description, String content, String type,
4297 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4298 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4299 boolean andOperator)
4300 throws SystemException {
4301
4302 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4303 companyId, groupId, folderIds, classNameId, articleId, version,
4304 title, description, content, type, ddmStructureKeys,
4305 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4306 andOperator, new QueryDefinition(status));
4307 }
4308
4309
4319 @Override
4320 public void subscribe(long userId, long groupId)
4321 throws PortalException, SystemException {
4322
4323 subscriptionLocalService.addSubscription(
4324 userId, groupId, JournalArticle.class.getName(), groupId);
4325 }
4326
4327
4337 @Override
4338 public void unsubscribe(long userId, long groupId)
4339 throws PortalException, SystemException {
4340
4341 subscriptionLocalService.deleteSubscription(
4342 userId, JournalArticle.class.getName(), groupId);
4343 }
4344
4345
4379 @Override
4380 public JournalArticle updateArticle(
4381 long userId, long groupId, long folderId, String articleId,
4382 double version, Map<Locale, String> titleMap,
4383 Map<Locale, String> descriptionMap, String content,
4384 String layoutUuid, ServiceContext serviceContext)
4385 throws PortalException, SystemException {
4386
4387 User user = userPersistence.findByPrimaryKey(userId);
4388
4389 JournalArticle article = journalArticlePersistence.findByG_A_V(
4390 groupId, articleId, version);
4391
4392 Date displayDate = article.getDisplayDate();
4393
4394 int displayDateMonth = 0;
4395 int displayDateDay = 0;
4396 int displayDateYear = 0;
4397 int displayDateHour = 0;
4398 int displayDateMinute = 0;
4399
4400 if (displayDate != null) {
4401 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4402 user.getTimeZone());
4403
4404 displayCal.setTime(displayDate);
4405
4406 displayDateMonth = displayCal.get(Calendar.MONTH);
4407 displayDateDay = displayCal.get(Calendar.DATE);
4408 displayDateYear = displayCal.get(Calendar.YEAR);
4409 displayDateHour = displayCal.get(Calendar.HOUR);
4410 displayDateMinute = displayCal.get(Calendar.MINUTE);
4411
4412 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4413 displayDateHour += 12;
4414 }
4415 }
4416
4417 Date expirationDate = article.getExpirationDate();
4418
4419 int expirationDateMonth = 0;
4420 int expirationDateDay = 0;
4421 int expirationDateYear = 0;
4422 int expirationDateHour = 0;
4423 int expirationDateMinute = 0;
4424 boolean neverExpire = true;
4425
4426 if (expirationDate != null) {
4427 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4428 user.getTimeZone());
4429
4430 expirationCal.setTime(expirationDate);
4431
4432 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4433 expirationDateDay = expirationCal.get(Calendar.DATE);
4434 expirationDateYear = expirationCal.get(Calendar.YEAR);
4435 expirationDateHour = expirationCal.get(Calendar.HOUR);
4436 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4437 neverExpire = false;
4438
4439 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4440 expirationDateHour += 12;
4441 }
4442 }
4443
4444 Date reviewDate = article.getReviewDate();
4445
4446 int reviewDateMonth = 0;
4447 int reviewDateDay = 0;
4448 int reviewDateYear = 0;
4449 int reviewDateHour = 0;
4450 int reviewDateMinute = 0;
4451 boolean neverReview = true;
4452
4453 if (reviewDate != null) {
4454 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4455 user.getTimeZone());
4456
4457 reviewCal.setTime(reviewDate);
4458
4459 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4460 reviewDateDay = reviewCal.get(Calendar.DATE);
4461 reviewDateYear = reviewCal.get(Calendar.YEAR);
4462 reviewDateHour = reviewCal.get(Calendar.HOUR);
4463 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4464 neverReview = false;
4465
4466 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4467 reviewDateHour += 12;
4468 }
4469 }
4470
4471 return updateArticle(
4472 userId, groupId, folderId, articleId, version, titleMap,
4473 descriptionMap, content, article.getType(),
4474 article.getStructureId(), article.getTemplateId(), layoutUuid,
4475 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4476 displayDateMinute, expirationDateMonth, expirationDateDay,
4477 expirationDateYear, expirationDateHour, expirationDateMinute,
4478 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4479 reviewDateHour, reviewDateMinute, neverReview,
4480 article.getIndexable(), article.isSmallImage(),
4481 article.getSmallImageURL(), null, null, null, serviceContext);
4482 }
4483
4484
4571 @Override
4572 public JournalArticle updateArticle(
4573 long userId, long groupId, long folderId, String articleId,
4574 double version, Map<Locale, String> titleMap,
4575 Map<Locale, String> descriptionMap, String content, String type,
4576 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4577 int displayDateMonth, int displayDateDay, int displayDateYear,
4578 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4579 int expirationDateDay, int expirationDateYear,
4580 int expirationDateHour, int expirationDateMinute,
4581 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4582 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4583 boolean neverReview, boolean indexable, boolean smallImage,
4584 String smallImageURL, File smallImageFile,
4585 Map<String, byte[]> images, String articleURL,
4586 ServiceContext serviceContext)
4587 throws PortalException, SystemException {
4588
4589
4590
4591 User user = userPersistence.findByPrimaryKey(userId);
4592 articleId = articleId.trim().toUpperCase();
4593
4594 byte[] smallImageBytes = null;
4595
4596 try {
4597 smallImageBytes = FileUtil.getBytes(smallImageFile);
4598 }
4599 catch (IOException ioe) {
4600 }
4601
4602 JournalArticle latestArticle = getLatestArticle(
4603 groupId, articleId, WorkflowConstants.STATUS_ANY);
4604
4605 JournalArticle article = latestArticle;
4606
4607 boolean imported = ExportImportThreadLocal.isImportInProcess();
4608
4609 double latestVersion = latestArticle.getVersion();
4610
4611 boolean addNewVersion = false;
4612
4613 if (imported) {
4614 if (latestVersion > version) {
4615 JournalArticle existingArticle =
4616 journalArticlePersistence.fetchByG_A_V(
4617 groupId, articleId, version);
4618
4619 if (existingArticle != null) {
4620 article = existingArticle;
4621 }
4622 else {
4623 addNewVersion = true;
4624 }
4625 }
4626 else if (latestVersion < version) {
4627 addNewVersion = true;
4628 }
4629 }
4630 else {
4631 if ((version > 0) && (version != latestVersion)) {
4632 throw new ArticleVersionException();
4633 }
4634
4635 serviceContext.validateModifiedDate(
4636 latestArticle, ArticleVersionException.class);
4637
4638 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4639 latestArticle.isScheduled()) {
4640
4641 addNewVersion = true;
4642
4643 version = MathUtil.format(latestVersion + 0.1, 1, 1);
4644 }
4645 }
4646
4647 Date displayDate = null;
4648 Date expirationDate = null;
4649 Date reviewDate = null;
4650
4651 if (article.getClassNameId() ==
4652 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4653
4654 displayDate = PortalUtil.getDate(
4655 displayDateMonth, displayDateDay, displayDateYear,
4656 displayDateHour, displayDateMinute, user.getTimeZone(),
4657 ArticleDisplayDateException.class);
4658
4659 if (!neverExpire) {
4660 expirationDate = PortalUtil.getDate(
4661 expirationDateMonth, expirationDateDay, expirationDateYear,
4662 expirationDateHour, expirationDateMinute,
4663 user.getTimeZone(), ArticleExpirationDateException.class);
4664 }
4665
4666 if (!neverReview) {
4667 reviewDate = PortalUtil.getDate(
4668 reviewDateMonth, reviewDateDay, reviewDateYear,
4669 reviewDateHour, reviewDateMinute, user.getTimeZone(),
4670 ArticleReviewDateException.class);
4671 }
4672 }
4673
4674 Date now = new Date();
4675
4676 boolean expired = false;
4677
4678 if ((expirationDate != null) && expirationDate.before(now)) {
4679 expired = true;
4680 }
4681
4682 validate(
4683 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
4684 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
4685 expirationDate, smallImage, smallImageURL, smallImageFile,
4686 smallImageBytes);
4687
4688 if (addNewVersion) {
4689 long id = counterLocalService.increment();
4690
4691 article = journalArticlePersistence.create(id);
4692
4693 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
4694 article.setGroupId(latestArticle.getGroupId());
4695 article.setCompanyId(latestArticle.getCompanyId());
4696 article.setUserId(user.getUserId());
4697 article.setUserName(user.getFullName());
4698 article.setCreateDate(serviceContext.getModifiedDate(now));
4699 article.setClassNameId(latestArticle.getClassNameId());
4700 article.setClassPK(latestArticle.getClassPK());
4701 article.setArticleId(articleId);
4702 article.setVersion(version);
4703 article.setSmallImageId(latestArticle.getSmallImageId());
4704 }
4705
4706 Locale locale = LocaleUtil.getSiteDefault();
4707
4708 String defaultLanguageId = ParamUtil.getString(
4709 serviceContext, "defaultLanguageId");
4710
4711 if (Validator.isNull(defaultLanguageId)) {
4712 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
4713 }
4714
4715 if (Validator.isNotNull(defaultLanguageId)) {
4716 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
4717 }
4718
4719 String title = titleMap.get(locale);
4720
4721 content = format(
4722 user, groupId, articleId, article.getVersion(), addNewVersion,
4723 content, ddmStructureKey, images);
4724
4725 article.setModifiedDate(serviceContext.getModifiedDate(now));
4726 article.setFolderId(folderId);
4727 article.setTitleMap(titleMap, locale);
4728 article.setUrlTitle(
4729 getUniqueUrlTitle(
4730 article.getId(), article.getArticleId(), title,
4731 latestArticle.getUrlTitle(), serviceContext));
4732 article.setDescriptionMap(descriptionMap, locale);
4733 article.setContent(content);
4734 article.setType(type);
4735 article.setStructureId(ddmStructureKey);
4736 article.setTemplateId(ddmTemplateKey);
4737 article.setLayoutUuid(layoutUuid);
4738 article.setDisplayDate(displayDate);
4739 article.setExpirationDate(expirationDate);
4740 article.setReviewDate(reviewDate);
4741 article.setIndexable(indexable);
4742 article.setSmallImage(smallImage);
4743
4744 if (smallImage) {
4745 if ((smallImageFile != null) && (smallImageBytes != null)) {
4746 article.setSmallImageId(counterLocalService.increment());
4747 }
4748 }
4749 else {
4750 article.setSmallImageId(0);
4751 }
4752
4753 article.setSmallImageURL(smallImageURL);
4754
4755 if (latestArticle.isPending()) {
4756 article.setStatus(latestArticle.getStatus());
4757 }
4758 else if (!expired) {
4759 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4760 }
4761 else {
4762 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
4763 }
4764
4765 article.setExpandoBridgeAttributes(serviceContext);
4766
4767 journalArticlePersistence.update(article);
4768
4769
4770
4771 updateAsset(
4772 userId, article, serviceContext.getAssetCategoryIds(),
4773 serviceContext.getAssetTagNames(),
4774 serviceContext.getAssetLinkEntryIds());
4775
4776
4777
4778 if (PortalUtil.getClassNameId(DDMStructure.class) ==
4779 article.getClassNameId()) {
4780
4781 updateDDMStructureXSD(
4782 article.getClassPK(), content, serviceContext);
4783 }
4784
4785
4786
4787 saveImages(
4788 smallImage, article.getSmallImageId(), smallImageFile,
4789 smallImageBytes);
4790
4791
4792
4793 PortletPreferences preferences =
4794 ServiceContextUtil.getPortletPreferences(serviceContext);
4795
4796
4797
4798 if (expired && imported) {
4799 updateStatus(
4800 userId, article, article.getStatus(), articleURL,
4801 new HashMap<String, Serializable>(), serviceContext);
4802 }
4803
4804 if (serviceContext.getWorkflowAction() ==
4805 WorkflowConstants.ACTION_PUBLISH) {
4806
4807 sendEmail(
4808 article, articleURL, preferences, "requested", serviceContext);
4809
4810 WorkflowHandlerRegistryUtil.startWorkflowInstance(
4811 user.getCompanyId(), groupId, userId,
4812 JournalArticle.class.getName(), article.getId(), article,
4813 serviceContext);
4814 }
4815 else if (article.getVersion() ==
4816 JournalArticleConstants.VERSION_DEFAULT) {
4817
4818
4819
4820 reindex(article);
4821 }
4822
4823 return journalArticlePersistence.findByPrimaryKey(article.getId());
4824 }
4825
4826
4855 @Override
4856 public JournalArticle updateArticle(
4857 long userId, long groupId, long folderId, String articleId,
4858 double version, String content, ServiceContext serviceContext)
4859 throws PortalException, SystemException {
4860
4861 JournalArticle article = journalArticlePersistence.findByG_A_V(
4862 groupId, articleId, version);
4863
4864 return updateArticle(
4865 userId, groupId, folderId, articleId, version,
4866 article.getTitleMap(), article.getDescriptionMap(), content,
4867 article.getLayoutUuid(), serviceContext);
4868 }
4869
4870
4875 @Override
4876 public JournalArticle updateArticleTranslation(
4877 long groupId, String articleId, double version, Locale locale,
4878 String title, String description, String content,
4879 Map<String, byte[]> images)
4880 throws PortalException, SystemException {
4881
4882 return updateArticleTranslation(
4883 groupId, articleId, version, locale, title, description, content,
4884 images, null);
4885 }
4886
4887
4909 @Override
4910 public JournalArticle updateArticleTranslation(
4911 long groupId, String articleId, double version, Locale locale,
4912 String title, String description, String content,
4913 Map<String, byte[]> images, ServiceContext serviceContext)
4914 throws PortalException, SystemException {
4915
4916 validateContent(content);
4917
4918 JournalArticle oldArticle = getLatestArticle(
4919 groupId, articleId, WorkflowConstants.STATUS_ANY);
4920
4921 double oldVersion = oldArticle.getVersion();
4922
4923 if ((version > 0) && (version != oldVersion)) {
4924 throw new ArticleVersionException();
4925 }
4926
4927 boolean incrementVersion = false;
4928
4929 if (oldArticle.isApproved() || oldArticle.isExpired()) {
4930 incrementVersion = true;
4931 }
4932
4933 if (serviceContext != null) {
4934 serviceContext.validateModifiedDate(
4935 oldArticle, ArticleVersionException.class);
4936 }
4937
4938 JournalArticle article = null;
4939
4940 User user = userPersistence.findByPrimaryKey(oldArticle.getUserId());
4941
4942 if (incrementVersion) {
4943 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
4944
4945 long id = counterLocalService.increment();
4946
4947 article = journalArticlePersistence.create(id);
4948
4949 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
4950 article.setGroupId(oldArticle.getGroupId());
4951 article.setCompanyId(oldArticle.getCompanyId());
4952 article.setUserId(oldArticle.getUserId());
4953 article.setUserName(user.getFullName());
4954 article.setCreateDate(new Date());
4955 article.setModifiedDate(new Date());
4956 article.setClassNameId(oldArticle.getClassNameId());
4957 article.setClassPK(oldArticle.getClassPK());
4958 article.setArticleId(articleId);
4959 article.setVersion(newVersion);
4960 article.setTitleMap(oldArticle.getTitleMap());
4961 article.setUrlTitle(
4962 getUniqueUrlTitle(
4963 id, articleId, title, oldArticle.getUrlTitle(),
4964 serviceContext));
4965 article.setDescriptionMap(oldArticle.getDescriptionMap());
4966 article.setType(oldArticle.getType());
4967 article.setStructureId(oldArticle.getStructureId());
4968 article.setTemplateId(oldArticle.getTemplateId());
4969 article.setLayoutUuid(oldArticle.getLayoutUuid());
4970 article.setDisplayDate(oldArticle.getDisplayDate());
4971 article.setExpirationDate(oldArticle.getExpirationDate());
4972 article.setReviewDate(oldArticle.getReviewDate());
4973 article.setIndexable(oldArticle.getIndexable());
4974 article.setSmallImage(oldArticle.getSmallImage());
4975 article.setSmallImageId(oldArticle.getSmallImageId());
4976
4977 if (article.getSmallImageId() == 0) {
4978 article.setSmallImageId(counterLocalService.increment());
4979 }
4980
4981 article.setSmallImageURL(oldArticle.getSmallImageURL());
4982
4983 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4984 article.setStatusDate(new Date());
4985 }
4986 else {
4987 article = oldArticle;
4988 }
4989
4990 Map<Locale, String> titleMap = article.getTitleMap();
4991
4992 titleMap.put(locale, title);
4993
4994 article.setTitleMap(titleMap);
4995
4996 Map<Locale, String> descriptionMap = article.getDescriptionMap();
4997
4998 descriptionMap.put(locale, description);
4999
5000 article.setDescriptionMap(descriptionMap);
5001
5002 content = format(
5003 user, groupId, articleId, article.getVersion(),
5004 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
5005 images);
5006
5007 article.setContent(content);
5008
5009 journalArticlePersistence.update(article);
5010
5011 return article;
5012 }
5013
5014
5027 @Override
5028 public void updateAsset(
5029 long userId, JournalArticle article, long[] assetCategoryIds,
5030 String[] assetTagNames, long[] assetLinkEntryIds)
5031 throws PortalException, SystemException {
5032
5033 boolean visible = article.isApproved();
5034
5035 if (article.getClassNameId() !=
5036 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5037
5038 visible = false;
5039 }
5040
5041 boolean addDraftAssetEntry = false;
5042
5043 if (!article.isApproved() &&
5044 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5045
5046 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5047 article.getGroupId(), article.getArticleId(),
5048 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5049
5050 if (approvedArticlesCount > 0) {
5051 addDraftAssetEntry = true;
5052 }
5053 }
5054
5055 AssetEntry assetEntry = null;
5056
5057 if (addDraftAssetEntry) {
5058 assetEntry = assetEntryLocalService.updateEntry(
5059 userId, article.getGroupId(), article.getCreateDate(),
5060 article.getModifiedDate(), JournalArticle.class.getName(),
5061 article.getPrimaryKey(), article.getUuid(),
5062 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5063 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5064 article.getDescription(), article.getDescription(), null,
5065 article.getLayoutUuid(), 0, 0, null, false);
5066 }
5067 else {
5068 JournalArticleResource journalArticleResource =
5069 journalArticleResourceLocalService.getArticleResource(
5070 article.getResourcePrimKey());
5071
5072 assetEntry = assetEntryLocalService.updateEntry(
5073 userId, article.getGroupId(), article.getCreateDate(),
5074 article.getModifiedDate(), JournalArticle.class.getName(),
5075 journalArticleResource.getResourcePrimKey(),
5076 journalArticleResource.getUuid(), getClassTypeId(article),
5077 assetCategoryIds, assetTagNames, visible, null, null, null,
5078 ContentTypes.TEXT_HTML, article.getTitle(),
5079 article.getDescription(), article.getDescription(), null,
5080 article.getLayoutUuid(), 0, 0, null, false);
5081 }
5082
5083 assetLinkLocalService.updateLinks(
5084 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5085 AssetLinkConstants.TYPE_RELATED);
5086 }
5087
5088
5103 @Override
5104 public JournalArticle updateContent(
5105 long groupId, String articleId, double version, String content)
5106 throws PortalException, SystemException {
5107
5108 JournalArticle article = journalArticlePersistence.findByG_A_V(
5109 groupId, articleId, version);
5110
5111 article.setContent(content);
5112
5113 journalArticlePersistence.update(article);
5114
5115 return article;
5116 }
5117
5118
5141 @Override
5142 public JournalArticle updateStatus(
5143 long userId, JournalArticle article, int status, String articleURL,
5144 Map<String, Serializable> workflowContext,
5145 ServiceContext serviceContext)
5146 throws PortalException, SystemException {
5147
5148
5149
5150 User user = userPersistence.findByPrimaryKey(userId);
5151 Date now = new Date();
5152
5153 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5154 (article.getClassNameId() ==
5155 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5156 (article.getDisplayDate() != null) &&
5157 now.before(article.getDisplayDate())) {
5158
5159 status = WorkflowConstants.STATUS_SCHEDULED;
5160 }
5161
5162 int oldStatus = article.getStatus();
5163
5164 int oldArticleVersionStatus = WorkflowConstants.STATUS_ANY;
5165
5166 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
5167 new ArrayList<ObjectValuePair<Long, Integer>>();
5168
5169 List<JournalArticle> articleVersions =
5170 (List<JournalArticle>)workflowContext.get("articleVersions");
5171
5172 if ((articleVersions != null) && !articleVersions.isEmpty()) {
5173 JournalArticle oldArticleVersion = articleVersions.get(0);
5174
5175 oldArticleVersionStatus = oldArticleVersion.getStatus();
5176
5177 articleVersionStatusOVPs = getArticleVersionStatuses(
5178 articleVersions);
5179 }
5180
5181 article.setModifiedDate(serviceContext.getModifiedDate(now));
5182
5183 boolean neverExpire = false;
5184
5185 if (status == WorkflowConstants.STATUS_APPROVED) {
5186 Date expirationDate = article.getExpirationDate();
5187
5188 if ((expirationDate != null) && expirationDate.before(now)) {
5189 neverExpire = true;
5190
5191 article.setExpirationDate(null);
5192 }
5193 }
5194
5195 if (status == WorkflowConstants.STATUS_EXPIRED) {
5196 article.setExpirationDate(now);
5197 }
5198
5199 article.setStatus(status);
5200 article.setStatusByUserId(user.getUserId());
5201 article.setStatusByUserName(user.getFullName());
5202 article.setStatusDate(serviceContext.getModifiedDate(now));
5203
5204 journalArticlePersistence.update(article);
5205
5206 if (hasModifiedLatestApprovedVersion(
5207 article.getGroupId(), article.getArticleId(),
5208 article.getVersion())) {
5209
5210 if (status == WorkflowConstants.STATUS_APPROVED) {
5211 updateUrlTitles(
5212 article.getGroupId(), article.getArticleId(),
5213 article.getUrlTitle());
5214
5215
5216
5217 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5218 (article.getVersion() !=
5219 JournalArticleConstants.VERSION_DEFAULT)) {
5220
5221 AssetEntry draftAssetEntry =
5222 assetEntryLocalService.fetchEntry(
5223 JournalArticle.class.getName(),
5224 article.getPrimaryKey());
5225
5226 if (draftAssetEntry != null) {
5227 long[] assetCategoryIds =
5228 draftAssetEntry.getCategoryIds();
5229 String[] assetTagNames = draftAssetEntry.getTagNames();
5230
5231 List<AssetLink> assetLinks =
5232 assetLinkLocalService.getDirectLinks(
5233 draftAssetEntry.getEntryId(),
5234 AssetLinkConstants.TYPE_RELATED);
5235
5236 long[] assetLinkEntryIds = StringUtil.split(
5237 ListUtil.toString(
5238 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5239
5240 AssetEntry assetEntry =
5241 assetEntryLocalService.updateEntry(
5242 userId, article.getGroupId(),
5243 article.getCreateDate(),
5244 article.getModifiedDate(),
5245 JournalArticle.class.getName(),
5246 article.getResourcePrimKey(), article.getUuid(),
5247 getClassTypeId(article), assetCategoryIds,
5248 assetTagNames, false, null, null, null,
5249 ContentTypes.TEXT_HTML, article.getTitle(),
5250 article.getDescription(),
5251 article.getDescription(), null,
5252 article.getLayoutUuid(), 0, 0, null, false);
5253
5254 assetLinkLocalService.updateLinks(
5255 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5256 AssetLinkConstants.TYPE_RELATED);
5257
5258 SystemEventHierarchyEntryThreadLocal.push(
5259 JournalArticle.class, 0,
5260 SystemEventConstants.ACTION_SKIP);
5261
5262 try {
5263 assetEntryLocalService.deleteEntry(
5264 JournalArticle.class.getName(),
5265 article.getPrimaryKey());
5266 }
5267 finally {
5268 SystemEventHierarchyEntryThreadLocal.pop();
5269 }
5270 }
5271 }
5272
5273 if (article.getClassNameId() ==
5274 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5275
5276
5277
5278
5279 Date[] dateInterval = getDateInterval(
5280 article.getGroupId(), article.getArticleId(),
5281 article.getDisplayDate(), article.getExpirationDate());
5282
5283 Date displayDate = dateInterval[0];
5284 Date expirationDate = dateInterval[1];
5285
5286 if (neverExpire) {
5287 expirationDate = null;
5288 }
5289
5290 assetEntryLocalService.updateEntry(
5291 JournalArticle.class.getName(),
5292 article.getResourcePrimKey(), displayDate,
5293 expirationDate, true);
5294 }
5295
5296
5297
5298 JSONObject extraDataJSONObject =
5299 JSONFactoryUtil.createJSONObject();
5300
5301 extraDataJSONObject.put("title", article.getTitle());
5302
5303 if (serviceContext.isCommandUpdate()) {
5304 socialActivityLocalService.addActivity(
5305 user.getUserId(), article.getGroupId(),
5306 JournalArticle.class.getName(),
5307 article.getResourcePrimKey(),
5308 JournalActivityKeys.UPDATE_ARTICLE,
5309 extraDataJSONObject.toString(), 0);
5310 }
5311 else {
5312 socialActivityLocalService.addUniqueActivity(
5313 user.getUserId(), article.getGroupId(),
5314 JournalArticle.class.getName(),
5315 article.getResourcePrimKey(),
5316 JournalActivityKeys.ADD_ARTICLE,
5317 extraDataJSONObject.toString(), 0);
5318 }
5319
5320
5321
5322 reindex(article);
5323 }
5324 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5325 updatePreviousApprovedArticle(article);
5326 }
5327 }
5328
5329 if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
5330
5331
5332
5333 List<TrashVersion> trashVersions =
5334 (List<TrashVersion>)workflowContext.get("trashVersions");
5335
5336 for (TrashVersion trashVersion : trashVersions) {
5337 JournalArticle trashArticleVersion =
5338 journalArticlePersistence.findByPrimaryKey(
5339 trashVersion.getClassPK());
5340
5341 trashArticleVersion.setStatus(trashVersion.getStatus());
5342
5343 journalArticlePersistence.update(trashArticleVersion);
5344 }
5345
5346 trashEntryLocalService.deleteEntry(
5347 JournalArticle.class.getName(), article.getResourcePrimKey());
5348
5349
5350
5351 if (status == WorkflowConstants.STATUS_APPROVED) {
5352 reindex(article);
5353 }
5354 else {
5355 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5356 JournalArticle.class);
5357
5358 indexer.delete(article);
5359 }
5360
5361 }
5362 else if (status == WorkflowConstants.STATUS_IN_TRASH) {
5363 assetEntryLocalService.updateVisible(
5364 JournalArticle.class.getName(), article.getResourcePrimKey(),
5365 false);
5366
5367
5368
5369 for (JournalArticle curArticleVersion : articleVersions) {
5370 curArticleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
5371
5372 journalArticlePersistence.update(curArticleVersion);
5373 }
5374
5375 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
5376
5377 typeSettingsProperties.put("title", article.getArticleId());
5378
5379 trashEntryLocalService.addTrashEntry(
5380 userId, article.getGroupId(), JournalArticle.class.getName(),
5381 article.getResourcePrimKey(), oldArticleVersionStatus,
5382 articleVersionStatusOVPs, typeSettingsProperties);
5383
5384
5385
5386 reindex(article);
5387 }
5388
5389 if ((article.getClassNameId() ==
5390 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5391 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5392 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5393
5394
5395
5396 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5397 ((status == WorkflowConstants.STATUS_APPROVED) ||
5398 (status == WorkflowConstants.STATUS_DENIED))) {
5399
5400 String msg = "granted";
5401
5402 if (status == WorkflowConstants.STATUS_DENIED) {
5403 msg = "denied";
5404 }
5405
5406 try {
5407 PortletPreferences preferences =
5408 ServiceContextUtil.getPortletPreferences(
5409 serviceContext);
5410
5411 sendEmail(
5412 article, articleURL, preferences, msg, serviceContext);
5413 }
5414 catch (Exception e) {
5415 _log.error(
5416 "Unable to send email to notify the change of status " +
5417 " to " + msg + " for article " + article.getId() +
5418 ": " + e.getMessage());
5419 }
5420 }
5421
5422
5423
5424 notifySubscribers(article, serviceContext);
5425 }
5426
5427 if (status == WorkflowConstants.STATUS_EXPIRED) {
5428 List<JournalArticle> approvedArticles =
5429 journalArticlePersistence.findByG_A_ST(
5430 article.getGroupId(), article.getArticleId(),
5431 WorkflowConstants.STATUS_APPROVED, 0, 1);
5432
5433 if (approvedArticles.isEmpty()) {
5434 reindex(article);
5435 }
5436 }
5437
5438 return article;
5439 }
5440
5441
5462 @Override
5463 public JournalArticle updateStatus(
5464 long userId, long classPK, int status,
5465 Map<String, Serializable> workflowContext,
5466 ServiceContext serviceContext)
5467 throws PortalException, SystemException {
5468
5469 JournalArticle article = getArticle(classPK);
5470
5471 return updateStatus(
5472 userId, article, status, null, workflowContext, serviceContext);
5473 }
5474
5475
5497 @Override
5498 public JournalArticle updateStatus(
5499 long userId, long groupId, String articleId, double version,
5500 int status, String articleURL,
5501 Map<String, Serializable> workflowContext,
5502 ServiceContext serviceContext)
5503 throws PortalException, SystemException {
5504
5505 JournalArticle article = journalArticlePersistence.findByG_A_V(
5506 groupId, articleId, version);
5507
5508 return updateStatus(
5509 userId, article, status, articleURL, workflowContext,
5510 serviceContext);
5511 }
5512
5513
5528 @Override
5529 public void updateTemplateId(
5530 long groupId, long classNameId, String oldDDMTemplateKey,
5531 String newDDMTemplateKey)
5532 throws SystemException {
5533
5534 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5535 groupId, classNameId, oldDDMTemplateKey);
5536
5537 for (JournalArticle article : articles) {
5538 article.setTemplateId(newDDMTemplateKey);
5539
5540 journalArticlePersistence.update(article);
5541 }
5542 }
5543
5544 protected void checkStructure(Document contentDoc, Element root)
5545 throws PortalException {
5546
5547 for (Element el : root.elements()) {
5548 checkStructureField(el, contentDoc);
5549
5550 checkStructure(contentDoc, el);
5551 }
5552 }
5553
5554 protected void checkStructure(JournalArticle article)
5555 throws PortalException, SystemException {
5556
5557 Group companyGroup = groupLocalService.getCompanyGroup(
5558 article.getCompanyId());
5559
5560 DDMStructure structure = null;
5561
5562 try {
5563 structure = ddmStructurePersistence.findByG_C_S(
5564 article.getGroupId(),
5565 PortalUtil.getClassNameId(JournalArticle.class),
5566 article.getStructureId());
5567 }
5568 catch (NoSuchStructureException nsse) {
5569 structure = ddmStructurePersistence.findByG_C_S(
5570 companyGroup.getGroupId(),
5571 PortalUtil.getClassNameId(JournalArticle.class),
5572 article.getStructureId());
5573 }
5574
5575 String content = GetterUtil.getString(article.getContent());
5576
5577 try {
5578 Document contentDocument = SAXReaderUtil.read(content);
5579 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5580
5581 checkStructure(contentDocument, xsdDocument.getRootElement());
5582 }
5583 catch (DocumentException de) {
5584 throw new SystemException(de);
5585 }
5586 catch (StructureXsdException sxsde) {
5587 long groupId = article.getGroupId();
5588 String articleId = article.getArticleId();
5589 double version = article.getVersion();
5590
5591 if (_log.isWarnEnabled()) {
5592 _log.warn(
5593 "Article {groupId=" + groupId + ", articleId=" +
5594 articleId + ", version=" + version +
5595 "} has content that does not match its " +
5596 "structure: " + sxsde.getMessage());
5597 }
5598 }
5599 }
5600
5601 protected void checkStructureField(Element el, Document contentDoc)
5602 throws PortalException {
5603
5604 StringBuilder elPath = new StringBuilder();
5605
5606 elPath.append(el.attributeValue("name"));
5607
5608 Element elParent = el.getParent();
5609
5610 for (;;) {
5611 if ((elParent == null) || elParent.getName().equals("root")) {
5612 break;
5613 }
5614
5615 elPath.insert(
5616 0, elParent.attributeValue("name") + StringPool.COMMA);
5617
5618 elParent = elParent.getParent();
5619 }
5620
5621 String[] elPathNames = StringUtil.split(elPath.toString());
5622
5623 Element contentEl = contentDoc.getRootElement();
5624
5625 for (String _elPathName : elPathNames) {
5626 boolean foundEl = false;
5627
5628 for (Element tempEl : contentEl.elements()) {
5629 if (_elPathName.equals(
5630 tempEl.attributeValue("name", StringPool.BLANK))) {
5631
5632 contentEl = tempEl;
5633 foundEl = true;
5634
5635 break;
5636 }
5637 }
5638
5639 if (!foundEl) {
5640 String elType = contentEl.attributeValue(
5641 "type", StringPool.BLANK);
5642
5643 if (!elType.equals("list") && !elType.equals("multi-list")) {
5644 throw new StructureXsdException(elPath.toString());
5645 }
5646
5647 break;
5648 }
5649 }
5650 }
5651
5652 protected void copyArticleImages(
5653 JournalArticle oldArticle, JournalArticle newArticle)
5654 throws Exception {
5655
5656 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5657
5658 XPath xPathSelector = SAXReaderUtil.createXPath(
5659 "
5660
5661 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5662
5663 for (Node imageNode : imageNodes) {
5664 Element imageEl = (Element)imageNode;
5665
5666 String instanceId = imageEl.attributeValue("instance-id");
5667 String name = imageEl.attributeValue("name");
5668
5669 List<Element> dynamicContentEls = imageEl.elements(
5670 "dynamic-content");
5671
5672 for (Element dynamicContentEl : dynamicContentEls) {
5673 long imageId = GetterUtil.getLong(
5674 dynamicContentEl.attributeValue("id"));
5675 String languageId = dynamicContentEl.attributeValue(
5676 "language-id");
5677
5678 Image oldImage = null;
5679
5680 try {
5681 oldImage = imageLocalService.getImage(imageId);
5682 }
5683 catch (NoSuchImageException nsie) {
5684 continue;
5685 }
5686
5687 imageId = journalArticleImageLocalService.getArticleImageId(
5688 newArticle.getGroupId(), newArticle.getArticleId(),
5689 newArticle.getVersion(), instanceId, name, languageId);
5690
5691 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5692
5693 String elContent =
5694 "/image/journal/article?img_id=" + imageId + "&t=" +
5695 WebServerServletTokenUtil.getToken(imageId);
5696
5697 dynamicContentEl.setText(elContent);
5698 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5699 }
5700 }
5701
5702 newArticle.setContent(contentDoc.formattedString());
5703 }
5704
5705 protected void format(
5706 User user, long groupId, String articleId, double version,
5707 boolean incrementVersion, Element root, Map<String, byte[]> images)
5708 throws PortalException, SystemException {
5709
5710 for (Element element : root.elements()) {
5711 String elInstanceId = element.attributeValue(
5712 "instance-id", StringPool.BLANK);
5713 String elType = element.attributeValue("type", StringPool.BLANK);
5714
5715 if (elType.equals("image")) {
5716 String elName = element.attributeValue(
5717 "name", StringPool.BLANK);
5718 String elIndex = element.attributeValue(
5719 "index", StringPool.BLANK);
5720
5721 String name = elName + "_" + elIndex;
5722
5723 formatImage(
5724 groupId, articleId, version, incrementVersion, element,
5725 elInstanceId, name, images);
5726 }
5727 else if (elType.equals("text_area") || elType.equals("text") ||
5728 elType.equals("text_box")) {
5729
5730 List<Element> dynamicContentElements = element.elements(
5731 "dynamic-content");
5732
5733 for (Element dynamicContentElement : dynamicContentElements) {
5734 String dynamicContent = dynamicContentElement.getText();
5735
5736 if (Validator.isNotNull(dynamicContent)) {
5737 String contentType = ContentTypes.TEXT_PLAIN;
5738
5739 if (elType.equals("text_area")) {
5740 contentType = ContentTypes.TEXT_HTML;
5741 }
5742
5743 dynamicContent = SanitizerUtil.sanitize(
5744 user.getCompanyId(), groupId, user.getUserId(),
5745 JournalArticle.class.getName(), 0, contentType,
5746 dynamicContent);
5747
5748 dynamicContentElement.clearContent();
5749
5750 dynamicContentElement.addCDATA(dynamicContent);
5751 }
5752 }
5753 }
5754
5755 format(
5756 user, groupId, articleId, version, incrementVersion, element,
5757 images);
5758 }
5759 }
5760
5761 protected String format(
5762 User user, long groupId, String articleId, double version,
5763 boolean incrementVersion, String content, String ddmStructureKey,
5764 Map<String, byte[]> images)
5765 throws PortalException, SystemException {
5766
5767 Document document = null;
5768
5769 try {
5770 document = SAXReaderUtil.read(content);
5771
5772 Element rootElement = document.getRootElement();
5773
5774 if (Validator.isNotNull(ddmStructureKey)) {
5775 format(
5776 user, groupId, articleId, version, incrementVersion,
5777 rootElement, images);
5778 }
5779 else {
5780 List<Element> staticContentElements = rootElement.elements(
5781 "static-content");
5782
5783 for (Element staticContentElement : staticContentElements) {
5784 String staticContent = staticContentElement.getText();
5785
5786 staticContent = SanitizerUtil.sanitize(
5787 user.getCompanyId(), groupId, user.getUserId(),
5788 JournalArticle.class.getName(), 0,
5789 ContentTypes.TEXT_HTML, staticContent);
5790
5791 staticContentElement.clearContent();
5792
5793 staticContentElement.addCDATA(staticContent);
5794 }
5795 }
5796
5797 content = DDMXMLUtil.formatXML(document);
5798 }
5799 catch (DocumentException de) {
5800 _log.error(de, de);
5801 }
5802
5803 content = HtmlUtil.replaceMsWordCharacters(content);
5804
5805 return content;
5806 }
5807
5808 protected void formatImage(
5809 long groupId, String articleId, double version,
5810 boolean incrementVersion, Element el, String elInstanceId,
5811 String elName, Map<String, byte[]> images)
5812 throws PortalException, SystemException {
5813
5814 List<Element> imageContents = el.elements("dynamic-content");
5815
5816 for (Element dynamicContent : imageContents) {
5817 String elLanguage = dynamicContent.attributeValue(
5818 "language-id", StringPool.BLANK);
5819
5820 if (!elLanguage.equals(StringPool.BLANK)) {
5821 elLanguage = "_" + elLanguage;
5822 }
5823
5824 long imageId = journalArticleImageLocalService.getArticleImageId(
5825 groupId, articleId, version, elInstanceId, elName, elLanguage);
5826
5827 if (dynamicContent.getText().equals("delete") ||
5828 Validator.isNull(dynamicContent.getText())) {
5829
5830 dynamicContent.setText(StringPool.BLANK);
5831
5832 imageLocalService.deleteImage(imageId);
5833
5834 String defaultElLanguage = "";
5835
5836 if (Validator.isNull(elLanguage)) {
5837 defaultElLanguage =
5838 "_" +
5839 LocaleUtil.toLanguageId(
5840 LocaleUtil.getSiteDefault());
5841 }
5842
5843 long defaultImageId =
5844 journalArticleImageLocalService.getArticleImageId(
5845 groupId, articleId, version, elInstanceId, elName,
5846 defaultElLanguage);
5847
5848 imageLocalService.deleteImage(defaultImageId);
5849
5850 continue;
5851 }
5852
5853 String elContent =
5854 "/image/journal/article?img_id=" + imageId + "&t=" +
5855 WebServerServletTokenUtil.getToken(imageId);
5856
5857 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
5858
5859 if ((bytes != null) && (bytes.length > 0)) {
5860 dynamicContent.setText(elContent);
5861 dynamicContent.addAttribute("id", String.valueOf(imageId));
5862
5863 imageLocalService.updateImage(imageId, bytes);
5864
5865 continue;
5866 }
5867
5868 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
5869 incrementVersion) {
5870
5871 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
5872
5873 long oldImageId = 0;
5874
5875 if ((oldVersion >= 1) && incrementVersion) {
5876 oldImageId =
5877 journalArticleImageLocalService.getArticleImageId(
5878 groupId, articleId, oldVersion, elInstanceId,
5879 elName, elLanguage);
5880 }
5881
5882 Image oldImage = null;
5883
5884 if (oldImageId > 0) {
5885 oldImage = imageLocalService.getImage(oldImageId);
5886 }
5887
5888 if (oldImage != null) {
5889 dynamicContent.setText(elContent);
5890 dynamicContent.addAttribute("id", String.valueOf(imageId));
5891
5892 bytes = oldImage.getTextObj();
5893
5894 imageLocalService.updateImage(imageId, bytes);
5895 }
5896 else if (dynamicContent.getText().equals("update")) {
5897 dynamicContent.setText(StringPool.BLANK);
5898 }
5899
5900 continue;
5901 }
5902
5903 Image image = imageLocalService.getImage(imageId);
5904
5905 if (image != null) {
5906 dynamicContent.setText(elContent);
5907 dynamicContent.addAttribute("id", String.valueOf(imageId));
5908
5909 continue;
5910 }
5911 else if (dynamicContent.getText().equals("update")) {
5912 dynamicContent.setText(StringPool.BLANK);
5913
5914 continue;
5915 }
5916
5917 long contentImageId = GetterUtil.getLong(
5918 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
5919
5920 if (contentImageId <= 0) {
5921 contentImageId = GetterUtil.getLong(
5922 HttpUtil.getParameter(
5923 dynamicContent.getText(), "img_id", false));
5924 }
5925
5926 if (contentImageId > 0) {
5927 image = imageLocalService.getImage(contentImageId);
5928
5929 if (image != null) {
5930 dynamicContent.addAttribute(
5931 "id", String.valueOf(contentImageId));
5932
5933 continue;
5934 }
5935 }
5936
5937 String defaultElLanguage = "";
5938
5939 if (Validator.isNull(elLanguage)) {
5940 defaultElLanguage =
5941 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
5942 }
5943
5944 long defaultImageId =
5945 journalArticleImageLocalService.getArticleImageId(
5946 groupId, articleId, version, elInstanceId, elName,
5947 defaultElLanguage);
5948
5949 Image defaultImage = imageLocalService.getImage(defaultImageId);
5950
5951 if (defaultImage != null) {
5952 dynamicContent.setText(elContent);
5953 dynamicContent.addAttribute(
5954 "id", String.valueOf(defaultImageId));
5955
5956 bytes = defaultImage.getTextObj();
5957
5958 imageLocalService.updateImage(defaultImageId, bytes);
5959
5960 continue;
5961 }
5962
5963 if (Validator.isNotNull(elLanguage)) {
5964 dynamicContent.setText(StringPool.BLANK);
5965 }
5966 }
5967 }
5968
5969 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
5970 List<JournalArticle> articles) {
5971
5972 List<ObjectValuePair<Long, Integer>> dlArticleVersionStatusOVPs =
5973 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
5974
5975 for (JournalArticle article : articles) {
5976 int status = article.getStatus();
5977
5978 if (status == WorkflowConstants.STATUS_PENDING) {
5979 status = WorkflowConstants.STATUS_DRAFT;
5980 }
5981
5982 ObjectValuePair<Long, Integer> dlFileVersionStatusOVP =
5983 new ObjectValuePair<Long, Integer>(article.getId(), status);
5984
5985 dlArticleVersionStatusOVPs.add(dlFileVersionStatusOVP);
5986 }
5987
5988 return dlArticleVersionStatusOVPs;
5989 }
5990
5991 protected long getClassTypeId(JournalArticle article) {
5992 long classTypeId = 0;
5993
5994 try {
5995 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
5996
5997 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
5998 article.getGroupId(), classNameId, article.getStructureId());
5999
6000 if (ddmStructure == null) {
6001 Group companyGroup = groupLocalService.getCompanyGroup(
6002 article.getCompanyId());
6003
6004 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6005 companyGroup.getGroupId(), classNameId,
6006 article.getStructureId());
6007 }
6008
6009 if (ddmStructure != null) {
6010 classTypeId = ddmStructure.getStructureId();
6011 }
6012 }
6013 catch (Exception e) {
6014 _log.error(e, e);
6015 }
6016
6017 return classTypeId;
6018 }
6019
6020 protected Date[] getDateInterval(
6021 long groupId, String articleId, Date earliestDisplayDate,
6022 Date latestExpirationDate)
6023 throws SystemException {
6024
6025 Date[] dateInterval = new Date[2];
6026
6027 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
6028 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6029
6030 boolean expiringArticle = true;
6031
6032 if (latestExpirationDate == null) {
6033 expiringArticle = false;
6034 }
6035
6036 for (JournalArticle article : articles) {
6037 if ((earliestDisplayDate == null) ||
6038 ((article.getDisplayDate() != null) &&
6039 earliestDisplayDate.after(article.getDisplayDate()))) {
6040
6041 earliestDisplayDate = article.getDisplayDate();
6042 }
6043
6044 if (expiringArticle &&
6045 ((latestExpirationDate == null) ||
6046 ((article.getExpirationDate() != null) &&
6047 latestExpirationDate.before(article.getExpirationDate())))) {
6048
6049 latestExpirationDate = article.getExpirationDate();
6050 }
6051
6052 if (expiringArticle && (article.getExpirationDate() == null) &&
6053 (latestExpirationDate != null)) {
6054
6055 expiringArticle = false;
6056 }
6057 }
6058
6059 dateInterval[0] = earliestDisplayDate;
6060 dateInterval[1] = latestExpirationDate;
6061
6062 return dateInterval;
6063 }
6064
6065 protected String getUniqueUrlTitle(
6066 long id, long groupId, String articleId, String title)
6067 throws PortalException, SystemException {
6068
6069 String urlTitle = JournalUtil.getUrlTitle(id, title);
6070
6071 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6072 }
6073
6074 protected String getUniqueUrlTitle(
6075 long id, String articleId, String title, String oldUrlTitle,
6076 ServiceContext serviceContext)
6077 throws PortalException, SystemException {
6078
6079 String serviceContextUrlTitle = ParamUtil.getString(
6080 serviceContext, "urlTitle");
6081
6082 String urlTitle = null;
6083
6084 if (Validator.isNotNull(serviceContextUrlTitle)) {
6085 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6086 }
6087 else if (Validator.isNotNull(oldUrlTitle)) {
6088 return oldUrlTitle;
6089 }
6090 else {
6091 urlTitle = getUniqueUrlTitle(
6092 id, serviceContext.getScopeGroupId(), articleId, title);
6093 }
6094
6095 JournalArticle urlTitleArticle = null;
6096
6097 try {
6098 urlTitleArticle = getArticleByUrlTitle(
6099 serviceContext.getScopeGroupId(), urlTitle);
6100 }
6101 catch (NoSuchArticleException nsae) {
6102 }
6103
6104 if ((urlTitleArticle != null) &&
6105 !Validator.equals(
6106 urlTitleArticle.getArticleId(), articleId)) {
6107
6108 urlTitle = getUniqueUrlTitle(
6109 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6110 }
6111
6112 return urlTitle;
6113 }
6114
6115 protected boolean hasModifiedLatestApprovedVersion(
6116 long groupId, String articleId, double version)
6117 throws PortalException, SystemException {
6118
6119 double latestApprovedVersion;
6120
6121 try {
6122 latestApprovedVersion = getLatestVersion(
6123 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6124
6125 if (version >= latestApprovedVersion) {
6126 return true;
6127 }
6128 else {
6129 return false;
6130 }
6131 }
6132 catch (NoSuchArticleException nsae) {
6133 return true;
6134 }
6135 }
6136
6137 protected void notifySubscribers(
6138 JournalArticle article, ServiceContext serviceContext)
6139 throws PortalException, SystemException {
6140
6141 if (!article.isApproved()) {
6142 return;
6143 }
6144
6145 String articleURL = PortalUtil.getControlPanelFullURL(
6146 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6147
6148 if (Validator.isNull(articleURL)) {
6149 return;
6150 }
6151
6152 PortletPreferences preferences =
6153 ServiceContextUtil.getPortletPreferences(serviceContext);
6154
6155 if (preferences == null) {
6156 long ownerId = article.getGroupId();
6157 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6158 long plid = PortletKeys.PREFS_PLID_SHARED;
6159 String portletId = PortletKeys.JOURNAL;
6160 String defaultPreferences = null;
6161
6162 preferences = portletPreferencesLocalService.getPreferences(
6163 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6164 defaultPreferences);
6165 }
6166
6167 if ((article.getVersion() == 1.0) &&
6168 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6169 }
6170 else if ((article.getVersion() != 1.0) &&
6171 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6172 }
6173 else {
6174 return;
6175 }
6176
6177 String fromName = JournalUtil.getEmailFromName(
6178 preferences, article.getCompanyId());
6179 String fromAddress = JournalUtil.getEmailFromAddress(
6180 preferences, article.getCompanyId());
6181
6182 String subject = null;
6183 String body = null;
6184
6185 if (article.getVersion() == 1.0) {
6186 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6187 body = JournalUtil.getEmailArticleAddedBody(preferences);
6188 }
6189 else {
6190 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6191 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6192 }
6193
6194 SubscriptionSender subscriptionSender = new SubscriptionSender();
6195
6196 subscriptionSender.setBody(body);
6197 subscriptionSender.setCompanyId(article.getCompanyId());
6198 subscriptionSender.setContextAttributes(
6199 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6200 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6201 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6202 subscriptionSender.setContextUserPrefix("ARTICLE");
6203 subscriptionSender.setFrom(fromAddress, fromName);
6204 subscriptionSender.setHtmlFormat(true);
6205 subscriptionSender.setMailId("journal_article", article.getId());
6206 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6207 subscriptionSender.setReplyToAddress(fromAddress);
6208 subscriptionSender.setScopeGroupId(article.getGroupId());
6209 subscriptionSender.setServiceContext(serviceContext);
6210 subscriptionSender.setSubject(subject);
6211 subscriptionSender.setUserId(article.getUserId());
6212
6213 subscriptionSender.addPersistedSubscribers(
6214 JournalArticle.class.getName(), article.getResourcePrimKey());
6215
6216 JournalFolder folder = article.getFolder();
6217
6218 List<Long> folderIds = new ArrayList<Long>();
6219
6220 if (folder != null) {
6221 folderIds.add(folder.getFolderId());
6222
6223 folderIds.addAll(folder.getAncestorFolderIds());
6224 }
6225
6226 for (long curFolderId : folderIds) {
6227 subscriptionSender.addPersistedSubscribers(
6228 JournalFolder.class.getName(), curFolderId);
6229 }
6230
6231 subscriptionSender.addPersistedSubscribers(
6232 JournalFolder.class.getName(), article.getGroupId());
6233
6234 subscriptionSender.flushNotificationsAsync();
6235 }
6236
6237 protected void reindex(JournalArticle article) throws SearchException {
6238 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6239 JournalArticle.class);
6240
6241 indexer.reindex(article);
6242 }
6243
6244 protected void saveImages(
6245 boolean smallImage, long smallImageId, File smallImageFile,
6246 byte[] smallImageBytes)
6247 throws PortalException, SystemException {
6248
6249 if (smallImage) {
6250 if ((smallImageFile != null) && (smallImageBytes != null)) {
6251 imageLocalService.updateImage(smallImageId, smallImageBytes);
6252 }
6253 }
6254 else {
6255 imageLocalService.deleteImage(smallImageId);
6256 }
6257 }
6258
6259 protected void sendEmail(
6260 JournalArticle article, String articleURL,
6261 PortletPreferences preferences, String emailType,
6262 ServiceContext serviceContext)
6263 throws PortalException, SystemException {
6264
6265 if (preferences == null) {
6266 return;
6267 }
6268 else if (emailType.equals("denied") &&
6269 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6270 preferences)) {
6271 }
6272 else if (emailType.equals("granted") &&
6273 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6274 preferences)) {
6275 }
6276 else if (emailType.equals("requested") &&
6277 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6278 preferences)) {
6279 }
6280 else if (emailType.equals("review") &&
6281 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6282 }
6283 else {
6284 return;
6285 }
6286
6287 Company company = companyPersistence.findByPrimaryKey(
6288 article.getCompanyId());
6289
6290 User user = userPersistence.findByPrimaryKey(article.getUserId());
6291
6292 articleURL +=
6293 "&groupId=" + article.getGroupId() + "&articleId=" +
6294 article.getArticleId() + "&version=" + article.getVersion();
6295
6296 String fromName = JournalUtil.getEmailFromName(
6297 preferences, article.getCompanyId());
6298 String fromAddress = JournalUtil.getEmailFromAddress(
6299 preferences, article.getCompanyId());
6300
6301 String toName = user.getFullName();
6302 String toAddress = user.getEmailAddress();
6303
6304 if (emailType.equals("requested") || emailType.equals("review")) {
6305 String tempToName = fromName;
6306 String tempToAddress = fromAddress;
6307
6308 fromName = toName;
6309 fromAddress = toAddress;
6310
6311 toName = tempToName;
6312 toAddress = tempToAddress;
6313 }
6314
6315 String subject = null;
6316 String body = null;
6317
6318 if (emailType.equals("denied")) {
6319 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6320 preferences);
6321 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6322 }
6323 else if (emailType.equals("granted")) {
6324 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6325 preferences);
6326 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6327 }
6328 else if (emailType.equals("requested")) {
6329 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6330 preferences);
6331 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6332 preferences);
6333 }
6334 else if (emailType.equals("review")) {
6335 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6336 body = JournalUtil.getEmailArticleReviewBody(preferences);
6337 }
6338
6339 SubscriptionSender subscriptionSender = new SubscriptionSender();
6340
6341 subscriptionSender.setBody(body);
6342 subscriptionSender.setCompanyId(company.getCompanyId());
6343 subscriptionSender.setContextAttributes(
6344 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6345 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6346 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6347 "[$ARTICLE_VERSION$]", article.getVersion());
6348 subscriptionSender.setContextUserPrefix("ARTICLE");
6349 subscriptionSender.setFrom(fromAddress, fromName);
6350 subscriptionSender.setHtmlFormat(true);
6351 subscriptionSender.setMailId("journal_article", article.getId());
6352 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6353 subscriptionSender.setScopeGroupId(article.getGroupId());
6354 subscriptionSender.setServiceContext(serviceContext);
6355 subscriptionSender.setSubject(subject);
6356 subscriptionSender.setUserId(article.getUserId());
6357
6358 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6359
6360 subscriptionSender.flushNotificationsAsync();
6361 }
6362
6363 protected void updateDDMStructureXSD(
6364 long ddmStructureId, String content, ServiceContext serviceContext)
6365 throws PortalException, SystemException {
6366
6367 try {
6368 Document document = SAXReaderUtil.read(content);
6369
6370 Element rootElement = document.getRootElement();
6371
6372 List<Element> elements = rootElement.elements();
6373
6374 for (Element element : elements) {
6375 String fieldName = element.attributeValue(
6376 "name", StringPool.BLANK);
6377
6378 List<Element> dynamicContentElements = element.elements(
6379 "dynamic-content");
6380
6381 for (Element dynamicContentElement : dynamicContentElements) {
6382 String value = dynamicContentElement.getText();
6383
6384 ddmStructureLocalService.updateXSDFieldMetadata(
6385 ddmStructureId, fieldName,
6386 FieldConstants.PREDEFINED_VALUE, value, serviceContext);
6387 }
6388 }
6389 }
6390 catch (DocumentException de) {
6391 throw new SystemException(de);
6392 }
6393 }
6394
6395 protected void updatePreviousApprovedArticle(JournalArticle article)
6396 throws PortalException, SystemException {
6397
6398 List<JournalArticle> approvedArticles =
6399 journalArticlePersistence.findByG_A_ST(
6400 article.getGroupId(), article.getArticleId(),
6401 WorkflowConstants.STATUS_APPROVED, 0, 2);
6402
6403 if (approvedArticles.isEmpty() ||
6404 ((approvedArticles.size() == 1) &&
6405 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6406
6407 if (article.isIndexable()) {
6408 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6409 JournalArticle.class);
6410
6411 indexer.delete(article);
6412 }
6413
6414 assetEntryLocalService.updateVisible(
6415 JournalArticle.class.getName(), article.getResourcePrimKey(),
6416 false);
6417 }
6418 else {
6419 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6420
6421 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6422 previousApprovedArticle = approvedArticles.get(1);
6423 }
6424
6425 Date[] dateInterval = getDateInterval(
6426 previousApprovedArticle.getGroupId(),
6427 previousApprovedArticle.getArticleId(),
6428 previousApprovedArticle.getDisplayDate(),
6429 previousApprovedArticle.getExpirationDate());
6430
6431 Date displayDate = dateInterval[0];
6432 Date expirationDate = dateInterval[1];
6433
6434 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6435 JournalArticle.class.getName(), article.getResourcePrimKey(),
6436 displayDate, expirationDate, true);
6437
6438 assetEntry.setModifiedDate(
6439 previousApprovedArticle.getModifiedDate());
6440
6441 assetEntryPersistence.update(assetEntry);
6442
6443 if (article.isIndexable()) {
6444 reindex(previousApprovedArticle);
6445 }
6446 }
6447 }
6448
6449 protected void updateUrlTitles(
6450 long groupId, String articleId, String urlTitle)
6451 throws SystemException {
6452
6453 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6454 groupId, articleId);
6455
6456 for (JournalArticle article : articles) {
6457 if (!article.getUrlTitle().equals(urlTitle)) {
6458 article.setUrlTitle(urlTitle);
6459
6460 journalArticlePersistence.update(article);
6461 }
6462 }
6463 }
6464
6465 protected void validate(
6466 long companyId, long groupId, long classNameId,
6467 Map<Locale, String> titleMap, String content, String type,
6468 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6469 boolean smallImage, String smallImageURL, File smallImageFile,
6470 byte[] smallImageBytes)
6471 throws PortalException, SystemException {
6472
6473 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6474 LocalizationUtil.getDefaultLanguageId(content));
6475
6476 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6477
6478 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6479 LocaleException le = new LocaleException(
6480 LocaleException.TYPE_CONTENT,
6481 "The locale " + articleDefaultLocale +
6482 " is not available in site with groupId" + groupId);
6483
6484 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6485
6486 le.setSourceAvailableLocales(sourceAvailableLocales);
6487 le.setTargetAvailableLocales(availableLocales);
6488
6489 throw le;
6490 }
6491
6492 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6493 (titleMap.isEmpty() ||
6494 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6495
6496 throw new ArticleTitleException();
6497 }
6498 else if (Validator.isNull(type)) {
6499 throw new ArticleTypeException();
6500 }
6501
6502 validateContent(content);
6503
6504 if (Validator.isNotNull(ddmStructureKey)) {
6505 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
6506
6507 DDMStructure ddmStructure = null;
6508
6509 try {
6510 ddmStructure = ddmStructurePersistence.findByG_C_S(
6511 groupId, PortalUtil.getClassNameId(JournalArticle.class),
6512 ddmStructureKey);
6513 }
6514 catch (NoSuchStructureException nsse) {
6515 ddmStructure = ddmStructurePersistence.findByG_C_S(
6516 companyGroup.getGroupId(),
6517 PortalUtil.getClassNameId(JournalArticle.class),
6518 ddmStructureKey);
6519 }
6520
6521 DDMTemplate ddmTemplate = null;
6522
6523 if (Validator.isNotNull(ddmTemplateKey)) {
6524 try {
6525 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6526 groupId, PortalUtil.getClassNameId(DDMStructure.class),
6527 ddmTemplateKey);
6528 }
6529 catch (NoSuchTemplateException nste) {
6530 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6531 companyGroup.getGroupId(),
6532 PortalUtil.getClassNameId(DDMStructure.class),
6533 ddmTemplateKey);
6534 }
6535
6536 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6537 throw new NoSuchTemplateException();
6538 }
6539 }
6540 else if (classNameId ==
6541 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6542
6543 throw new NoSuchTemplateException();
6544 }
6545 }
6546
6547 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6548 !ExportImportThreadLocal.isImportInProcess()) {
6549
6550 throw new ArticleExpirationDateException();
6551 }
6552
6553 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6554 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6555
6556 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6557 (smallImageFile == null) || (smallImageBytes == null)) {
6558
6559 return;
6560 }
6561
6562 String smallImageName = smallImageFile.getName();
6563
6564 if (smallImageName != null) {
6565 boolean validSmallImageExtension = false;
6566
6567 for (String _imageExtension : imageExtensions) {
6568 if (StringPool.STAR.equals(_imageExtension) ||
6569 StringUtil.endsWith(smallImageName, _imageExtension)) {
6570
6571 validSmallImageExtension = true;
6572
6573 break;
6574 }
6575 }
6576
6577 if (!validSmallImageExtension) {
6578 throw new ArticleSmallImageNameException(smallImageName);
6579 }
6580 }
6581
6582 long smallImageMaxSize = PrefsPropsUtil.getLong(
6583 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6584
6585 if ((smallImageMaxSize > 0) &&
6586 ((smallImageBytes == null) ||
6587 (smallImageBytes.length > smallImageMaxSize))) {
6588
6589 throw new ArticleSmallImageSizeException();
6590 }
6591 }
6592
6593 protected void validate(
6594 long companyId, long groupId, long classNameId, String articleId,
6595 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6596 String content, String type, String ddmStructureKey,
6597 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6598 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
6599 throws PortalException, SystemException {
6600
6601 if (!autoArticleId) {
6602 validate(articleId);
6603 }
6604
6605 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6606 groupId, articleId, version);
6607
6608 if (article != null) {
6609 throw new DuplicateArticleIdException();
6610 }
6611
6612 validate(
6613 companyId, groupId, classNameId, titleMap, content, type,
6614 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6615 smallImageURL, smallImageFile, smallImageBytes);
6616 }
6617
6618 protected void validate(String articleId) throws PortalException {
6619 if (Validator.isNull(articleId) ||
6620 (articleId.indexOf(CharPool.SPACE) != -1)) {
6621
6622 throw new ArticleIdException();
6623 }
6624 }
6625
6626 protected void validateContent(String content) throws PortalException {
6627 if (Validator.isNull(content)) {
6628 throw new ArticleContentException("Content is null");
6629 }
6630
6631 try {
6632 SAXReaderUtil.read(content);
6633 }
6634 catch (DocumentException de) {
6635 if (_log.isDebugEnabled()) {
6636 _log.debug("Invalid content:\n" + content);
6637 }
6638
6639 throw new ArticleContentException(
6640 "Unable to read content with an XML parser", de);
6641 }
6642 }
6643
6644 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
6645 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
6646
6647 private static Log _log = LogFactoryUtil.getLog(
6648 JournalArticleLocalServiceImpl.class);
6649
6650 private Date _previousCheckDate;
6651
6652 }