001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
020 import com.liferay.portal.kernel.dao.orm.Property;
021 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
022 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
023 import com.liferay.portal.kernel.dao.orm.QueryUtil;
024 import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
025 import com.liferay.portal.kernel.exception.PortalException;
026 import com.liferay.portal.kernel.exception.SystemException;
027 import com.liferay.portal.kernel.json.JSONFactoryUtil;
028 import com.liferay.portal.kernel.json.JSONObject;
029 import com.liferay.portal.kernel.language.LanguageUtil;
030 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
031 import com.liferay.portal.kernel.log.Log;
032 import com.liferay.portal.kernel.log.LogFactoryUtil;
033 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
034 import com.liferay.portal.kernel.search.Field;
035 import com.liferay.portal.kernel.search.Hits;
036 import com.liferay.portal.kernel.search.Indexable;
037 import com.liferay.portal.kernel.search.IndexableType;
038 import com.liferay.portal.kernel.search.Indexer;
039 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
040 import com.liferay.portal.kernel.search.QueryConfig;
041 import com.liferay.portal.kernel.search.SearchContext;
042 import com.liferay.portal.kernel.search.Sort;
043 import com.liferay.portal.kernel.systemevent.SystemEvent;
044 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
045 import com.liferay.portal.kernel.template.TemplateConstants;
046 import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
047 import com.liferay.portal.kernel.util.ArrayUtil;
048 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
049 import com.liferay.portal.kernel.util.CharPool;
050 import com.liferay.portal.kernel.util.Constants;
051 import com.liferay.portal.kernel.util.ContentTypes;
052 import com.liferay.portal.kernel.util.FileUtil;
053 import com.liferay.portal.kernel.util.GetterUtil;
054 import com.liferay.portal.kernel.util.HtmlUtil;
055 import com.liferay.portal.kernel.util.HttpUtil;
056 import com.liferay.portal.kernel.util.ListUtil;
057 import com.liferay.portal.kernel.util.LocaleUtil;
058 import com.liferay.portal.kernel.util.LocalizationUtil;
059 import com.liferay.portal.kernel.util.MathUtil;
060 import com.liferay.portal.kernel.util.ObjectValuePair;
061 import com.liferay.portal.kernel.util.OrderByComparator;
062 import com.liferay.portal.kernel.util.ParamUtil;
063 import com.liferay.portal.kernel.util.PropsKeys;
064 import com.liferay.portal.kernel.util.StringBundler;
065 import com.liferay.portal.kernel.util.StringPool;
066 import com.liferay.portal.kernel.util.StringUtil;
067 import com.liferay.portal.kernel.util.Time;
068 import com.liferay.portal.kernel.util.UnicodeProperties;
069 import com.liferay.portal.kernel.util.Validator;
070 import com.liferay.portal.kernel.workflow.WorkflowConstants;
071 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
072 import com.liferay.portal.kernel.xml.Document;
073 import com.liferay.portal.kernel.xml.DocumentException;
074 import com.liferay.portal.kernel.xml.Element;
075 import com.liferay.portal.kernel.xml.Node;
076 import com.liferay.portal.kernel.xml.SAXReaderUtil;
077 import com.liferay.portal.kernel.xml.XPath;
078 import com.liferay.portal.model.Company;
079 import com.liferay.portal.model.Group;
080 import com.liferay.portal.model.Image;
081 import com.liferay.portal.model.ResourceConstants;
082 import com.liferay.portal.model.SystemEventConstants;
083 import com.liferay.portal.model.User;
084 import com.liferay.portal.service.ServiceContext;
085 import com.liferay.portal.service.ServiceContextUtil;
086 import com.liferay.portal.servlet.filters.cache.CacheUtil;
087 import com.liferay.portal.theme.ThemeDisplay;
088 import com.liferay.portal.util.PortalUtil;
089 import com.liferay.portal.util.PortletKeys;
090 import com.liferay.portal.util.PrefsPropsUtil;
091 import com.liferay.portal.util.PropsValues;
092 import com.liferay.portal.util.SubscriptionSender;
093 import com.liferay.portal.webserver.WebServerServletTokenUtil;
094 import com.liferay.portlet.asset.model.AssetEntry;
095 import com.liferay.portlet.asset.model.AssetLink;
096 import com.liferay.portlet.asset.model.AssetLinkConstants;
097 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
098 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
099 import com.liferay.portlet.dynamicdatamapping.StorageFieldNameException;
100 import com.liferay.portlet.dynamicdatamapping.StorageFieldRequiredException;
101 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
102 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
103 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
104 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
105 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
106 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
107 import com.liferay.portlet.expando.util.ExpandoBridgeUtil;
108 import com.liferay.portlet.journal.ArticleContentException;
109 import com.liferay.portlet.journal.ArticleDisplayDateException;
110 import com.liferay.portlet.journal.ArticleExpirationDateException;
111 import com.liferay.portlet.journal.ArticleIdException;
112 import com.liferay.portlet.journal.ArticleReviewDateException;
113 import com.liferay.portlet.journal.ArticleSmallImageNameException;
114 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
115 import com.liferay.portlet.journal.ArticleTitleException;
116 import com.liferay.portlet.journal.ArticleTypeException;
117 import com.liferay.portlet.journal.ArticleVersionException;
118 import com.liferay.portlet.journal.DuplicateArticleIdException;
119 import com.liferay.portlet.journal.NoSuchArticleException;
120 import com.liferay.portlet.journal.NoSuchArticleImageException;
121 import com.liferay.portlet.journal.StructureXsdException;
122 import com.liferay.portlet.journal.model.JournalArticle;
123 import com.liferay.portlet.journal.model.JournalArticleConstants;
124 import com.liferay.portlet.journal.model.JournalArticleDisplay;
125 import com.liferay.portlet.journal.model.JournalArticleResource;
126 import com.liferay.portlet.journal.model.JournalFolder;
127 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
128 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
129 import com.liferay.portlet.journal.service.persistence.JournalArticleActionableDynamicQuery;
130 import com.liferay.portlet.journal.social.JournalActivityKeys;
131 import com.liferay.portlet.journal.util.JournalConverterUtil;
132 import com.liferay.portlet.journal.util.JournalUtil;
133 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
134 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
135 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
136 import com.liferay.portlet.social.model.SocialActivityConstants;
137 import com.liferay.portlet.trash.model.TrashEntry;
138 import com.liferay.portlet.trash.model.TrashVersion;
139 import com.liferay.portlet.trash.util.TrashUtil;
140 import com.liferay.util.portlet.PortletRequestUtil;
141
142 import java.io.File;
143 import java.io.IOException;
144 import java.io.Serializable;
145
146 import java.util.ArrayList;
147 import java.util.Calendar;
148 import java.util.Date;
149 import java.util.HashMap;
150 import java.util.HashSet;
151 import java.util.LinkedHashMap;
152 import java.util.List;
153 import java.util.Locale;
154 import java.util.Map;
155 import java.util.Set;
156 import java.util.concurrent.Callable;
157
158 import javax.portlet.PortletPreferences;
159
160
189 public class JournalArticleLocalServiceImpl
190 extends JournalArticleLocalServiceBaseImpl {
191
192
275 @Indexable(type = IndexableType.REINDEX)
276 @Override
277 public JournalArticle addArticle(
278 long userId, long groupId, long folderId, long classNameId,
279 long classPK, String articleId, boolean autoArticleId,
280 double version, Map<Locale, String> titleMap,
281 Map<Locale, String> descriptionMap, String content, String type,
282 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
283 int displayDateMonth, int displayDateDay, int displayDateYear,
284 int displayDateHour, int displayDateMinute, int expirationDateMonth,
285 int expirationDateDay, int expirationDateYear,
286 int expirationDateHour, int expirationDateMinute,
287 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
288 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
289 boolean neverReview, boolean indexable, boolean smallImage,
290 String smallImageURL, File smallImageFile,
291 Map<String, byte[]> images, String articleURL,
292 ServiceContext serviceContext)
293 throws PortalException, SystemException {
294
295
296
297 User user = userPersistence.findByPrimaryKey(userId);
298 articleId = StringUtil.toUpperCase(articleId.trim());
299
300 Date displayDate = null;
301 Date expirationDate = null;
302 Date reviewDate = null;
303
304 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
305 displayDate = PortalUtil.getDate(
306 displayDateMonth, displayDateDay, displayDateYear,
307 displayDateHour, displayDateMinute, user.getTimeZone(),
308 ArticleDisplayDateException.class);
309
310 if (!neverExpire) {
311 expirationDate = PortalUtil.getDate(
312 expirationDateMonth, expirationDateDay, expirationDateYear,
313 expirationDateHour, expirationDateMinute,
314 user.getTimeZone(), ArticleExpirationDateException.class);
315 }
316
317 if (!neverReview) {
318 reviewDate = PortalUtil.getDate(
319 reviewDateMonth, reviewDateDay, reviewDateYear,
320 reviewDateHour, reviewDateMinute, user.getTimeZone(),
321 ArticleReviewDateException.class);
322 }
323 }
324
325 byte[] smallImageBytes = null;
326
327 try {
328 smallImageBytes = FileUtil.getBytes(smallImageFile);
329 }
330 catch (IOException ioe) {
331 }
332
333 Date now = new Date();
334
335 if (autoArticleId) {
336 articleId = String.valueOf(counterLocalService.increment());
337 }
338
339 validate(
340 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
341 version, titleMap, content, type, ddmStructureKey, ddmTemplateKey,
342 displayDate, expirationDate, smallImage, smallImageURL,
343 smallImageFile, smallImageBytes, serviceContext);
344
345 serviceContext.setAttribute("articleId", articleId);
346
347 long id = counterLocalService.increment();
348
349 long resourcePrimKey =
350 journalArticleResourceLocalService.getArticleResourcePrimKey(
351 serviceContext.getUuid(), groupId, articleId);
352
353 JournalArticle article = journalArticlePersistence.create(id);
354
355 Locale locale = getArticleDefaultLocale(content, serviceContext);
356
357 String title = titleMap.get(locale);
358
359 content = format(
360 user, groupId, articleId, version, false, content, ddmStructureKey,
361 images);
362
363 article.setResourcePrimKey(resourcePrimKey);
364 article.setGroupId(groupId);
365 article.setCompanyId(user.getCompanyId());
366 article.setUserId(user.getUserId());
367 article.setUserName(user.getFullName());
368 article.setCreateDate(serviceContext.getCreateDate(now));
369 article.setModifiedDate(serviceContext.getModifiedDate(now));
370 article.setFolderId(folderId);
371 article.setClassNameId(classNameId);
372 article.setClassPK(classPK);
373 article.setTreePath(article.buildTreePath());
374 article.setArticleId(articleId);
375 article.setVersion(version);
376 article.setTitleMap(titleMap, locale);
377 article.setUrlTitle(
378 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
379 article.setDescriptionMap(descriptionMap, locale);
380 article.setContent(content);
381 article.setType(type);
382 article.setStructureId(ddmStructureKey);
383 article.setTemplateId(ddmTemplateKey);
384 article.setLayoutUuid(layoutUuid);
385 article.setDisplayDate(displayDate);
386 article.setExpirationDate(expirationDate);
387 article.setReviewDate(reviewDate);
388 article.setIndexable(indexable);
389 article.setSmallImage(smallImage);
390 article.setSmallImageId(counterLocalService.increment());
391 article.setSmallImageURL(smallImageURL);
392
393 if ((expirationDate == null) || expirationDate.after(now)) {
394 article.setStatus(WorkflowConstants.STATUS_DRAFT);
395 }
396 else {
397 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
398 }
399
400 article.setStatusByUserId(userId);
401 article.setStatusDate(serviceContext.getModifiedDate(now));
402 article.setExpandoBridgeAttributes(serviceContext);
403
404 journalArticlePersistence.update(article);
405
406
407
408 if (serviceContext.isAddGroupPermissions() ||
409 serviceContext.isAddGuestPermissions()) {
410
411 addArticleResources(
412 article, serviceContext.isAddGroupPermissions(),
413 serviceContext.isAddGuestPermissions());
414 }
415 else {
416 addArticleResources(
417 article, serviceContext.getGroupPermissions(),
418 serviceContext.getGuestPermissions());
419 }
420
421
422
423 saveImages(
424 smallImage, article.getSmallImageId(), smallImageFile,
425 smallImageBytes);
426
427
428
429 updateAsset(
430 userId, article, serviceContext.getAssetCategoryIds(),
431 serviceContext.getAssetTagNames(),
432 serviceContext.getAssetLinkEntryIds());
433
434
435
436 if (PortalUtil.getClassNameId(DDMStructure.class) == classNameId) {
437 updateDDMStructureXSD(classPK, content, serviceContext);
438 }
439
440
441
442 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
443 mbMessageLocalService.addDiscussionMessage(
444 userId, article.getUserName(), groupId,
445 JournalArticle.class.getName(), resourcePrimKey,
446 WorkflowConstants.ACTION_PUBLISH);
447 }
448
449
450
451 PortletPreferences preferences =
452 ServiceContextUtil.getPortletPreferences(serviceContext);
453
454 articleURL = buildArticleURL(articleURL, groupId, folderId, articleId);
455
456 serviceContext.setAttribute("articleURL", articleURL);
457
458 sendEmail(
459 article, articleURL, preferences, "requested", serviceContext);
460
461
462
463 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
464 WorkflowHandlerRegistryUtil.startWorkflowInstance(
465 user.getCompanyId(), groupId, userId,
466 JournalArticle.class.getName(), article.getId(), article,
467 serviceContext);
468 }
469 else {
470 updateStatus(
471 userId, article, WorkflowConstants.STATUS_APPROVED, null,
472 new HashMap<String, Serializable>(), serviceContext);
473 }
474
475 return journalArticlePersistence.findByPrimaryKey(article.getId());
476 }
477
478
507 @Override
508 public JournalArticle addArticle(
509 long userId, long groupId, long folderId,
510 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
511 String content, String ddmStructureKey, String ddmTemplateKey,
512 ServiceContext serviceContext)
513 throws PortalException, SystemException {
514
515 User user = userPersistence.findByPrimaryKey(userId);
516
517 Calendar calendar = CalendarFactoryUtil.getCalendar(user.getTimeZone());
518
519 int displayDateMonth = calendar.get(Calendar.MONTH);
520 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
521 int displayDateYear = calendar.get(Calendar.YEAR);
522 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
523 int displayDateMinute = calendar.get(Calendar.MINUTE);
524
525 return journalArticleLocalService.addArticle(
526 userId, groupId, folderId,
527 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
528 true, 1, titleMap, descriptionMap, content, "general",
529 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
530 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
531 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
532 null, null, serviceContext);
533 }
534
535
545 @Override
546 public void addArticleResources(
547 JournalArticle article, boolean addGroupPermissions,
548 boolean addGuestPermissions)
549 throws PortalException, SystemException {
550
551 resourceLocalService.addResources(
552 article.getCompanyId(), article.getGroupId(), article.getUserId(),
553 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
554 addGroupPermissions, addGuestPermissions);
555 }
556
557
566 @Override
567 public void addArticleResources(
568 JournalArticle article, String[] groupPermissions,
569 String[] guestPermissions)
570 throws PortalException, SystemException {
571
572 resourceLocalService.addModelResources(
573 article.getCompanyId(), article.getGroupId(), article.getUserId(),
574 JournalArticle.class.getName(), article.getResourcePrimKey(),
575 groupPermissions, guestPermissions);
576 }
577
578
588 @Override
589 public void addArticleResources(
590 long groupId, String articleId, boolean addGroupPermissions,
591 boolean addGuestPermissions)
592 throws PortalException, SystemException {
593
594 JournalArticle article = getLatestArticle(groupId, articleId);
595
596 addArticleResources(article, addGroupPermissions, addGuestPermissions);
597 }
598
599
610 @Override
611 public void addArticleResources(
612 long groupId, String articleId, String[] groupPermissions,
613 String[] guestPermissions)
614 throws PortalException, SystemException {
615
616 JournalArticle article = getLatestArticle(groupId, articleId);
617
618 addArticleResources(article, groupPermissions, guestPermissions);
619 }
620
621
634 @Override
635 public JournalArticle checkArticleResourcePrimKey(
636 long groupId, String articleId, double version)
637 throws PortalException, SystemException {
638
639 JournalArticle article = journalArticlePersistence.findByG_A_V(
640 groupId, articleId, version);
641
642 if (article.getResourcePrimKey() > 0) {
643 return article;
644 }
645
646 long resourcePrimKey =
647 journalArticleResourceLocalService.getArticleResourcePrimKey(
648 groupId, articleId);
649
650 article.setResourcePrimKey(resourcePrimKey);
651
652 journalArticlePersistence.update(article);
653
654 return article;
655 }
656
657
664 @Override
665 public void checkArticles() throws PortalException, SystemException {
666 Date now = new Date();
667
668 checkArticlesByExpirationDate(now);
669
670 checkArticlesByReviewDate(now);
671
672 checkArticlesByDisplayDate(now);
673
674 _previousCheckDate = now;
675 }
676
677
689 @Override
690 public void checkNewLine(long groupId, String articleId, double version)
691 throws PortalException, SystemException {
692
693 JournalArticle article = journalArticlePersistence.findByG_A_V(
694 groupId, articleId, version);
695
696 String content = GetterUtil.getString(article.getContent());
697
698 if (content.contains("\\n")) {
699 content = StringUtil.replace(
700 content, new String[] {"\\n", "\\r"},
701 new String[] {"\n", "\r"});
702
703 article.setContent(content);
704
705 journalArticlePersistence.update(article);
706 }
707 }
708
709
722 @Override
723 public void checkStructure(long groupId, String articleId, double version)
724 throws PortalException, SystemException {
725
726 JournalArticle article = journalArticlePersistence.findByG_A_V(
727 groupId, articleId, version);
728
729 if (Validator.isNull(article.getStructureId())) {
730 return;
731 }
732
733 checkStructure(article);
734 }
735
736
752 @Indexable(type = IndexableType.REINDEX)
753 @Override
754 public JournalArticle copyArticle(
755 long userId, long groupId, String oldArticleId, String newArticleId,
756 boolean autoArticleId, double version)
757 throws PortalException, SystemException {
758
759
760
761 User user = userPersistence.findByPrimaryKey(userId);
762 oldArticleId = StringUtil.toUpperCase(oldArticleId.trim());
763 newArticleId = StringUtil.toUpperCase(newArticleId.trim());
764 Date now = new Date();
765
766 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
767 groupId, oldArticleId, version);
768
769 if (autoArticleId) {
770 newArticleId = String.valueOf(counterLocalService.increment());
771 }
772 else {
773 validate(newArticleId);
774
775 if (journalArticlePersistence.countByG_A(
776 groupId, newArticleId) > 0) {
777
778 StringBundler sb = new StringBundler(5);
779
780 sb.append("{groupId=");
781 sb.append(groupId);
782 sb.append(", articleId=");
783 sb.append(newArticleId);
784 sb.append("}");
785
786 throw new DuplicateArticleIdException(sb.toString());
787 }
788 }
789
790 long id = counterLocalService.increment();
791
792 long resourcePrimKey =
793 journalArticleResourceLocalService.getArticleResourcePrimKey(
794 groupId, newArticleId);
795
796 JournalArticle newArticle = journalArticlePersistence.create(id);
797
798 newArticle.setResourcePrimKey(resourcePrimKey);
799 newArticle.setGroupId(groupId);
800 newArticle.setCompanyId(user.getCompanyId());
801 newArticle.setUserId(user.getUserId());
802 newArticle.setUserName(user.getFullName());
803 newArticle.setCreateDate(now);
804 newArticle.setModifiedDate(now);
805 newArticle.setFolderId(oldArticle.getFolderId());
806 newArticle.setTreePath(oldArticle.getTreePath());
807 newArticle.setArticleId(newArticleId);
808 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
809 newArticle.setTitle(oldArticle.getTitle());
810 newArticle.setUrlTitle(
811 getUniqueUrlTitle(
812 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
813 newArticle.setDescription(oldArticle.getDescription());
814
815 try {
816 copyArticleImages(oldArticle, newArticle);
817 }
818 catch (Exception e) {
819 newArticle.setContent(oldArticle.getContent());
820 }
821
822 newArticle.setType(oldArticle.getType());
823 newArticle.setStructureId(oldArticle.getStructureId());
824 newArticle.setTemplateId(oldArticle.getTemplateId());
825 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
826 newArticle.setDisplayDate(oldArticle.getDisplayDate());
827 newArticle.setExpirationDate(oldArticle.getExpirationDate());
828 newArticle.setReviewDate(oldArticle.getReviewDate());
829 newArticle.setIndexable(oldArticle.isIndexable());
830 newArticle.setSmallImage(oldArticle.isSmallImage());
831 newArticle.setSmallImageId(counterLocalService.increment());
832 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
833
834 if (oldArticle.isPending() ||
835 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
836 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
837
838 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
839 }
840 else {
841 newArticle.setStatus(oldArticle.getStatus());
842 }
843
844 ExpandoBridgeUtil.copyExpandoBridgeAttributes(
845 oldArticle.getExpandoBridge(), newArticle.getExpandoBridge());
846
847 journalArticlePersistence.update(newArticle);
848
849
850
851 addArticleResources(newArticle, true, true);
852
853
854
855 if (oldArticle.isSmallImage()) {
856 Image image = imageLocalService.fetchImage(
857 oldArticle.getSmallImageId());
858
859 if (image != null) {
860 byte[] smallImageBytes = image.getTextObj();
861
862 imageLocalService.updateImage(
863 newArticle.getSmallImageId(), smallImageBytes);
864 }
865 }
866
867
868
869 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
870 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
871 String[] assetTagNames = assetTagLocalService.getTagNames(
872 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
873
874 AssetEntry oldAssetEntry = assetEntryLocalService.getEntry(
875 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
876
877 List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
878 oldAssetEntry.getEntryId(), false);
879
880 long[] assetLinkEntryIds = StringUtil.split(
881 ListUtil.toString(assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
882
883 updateAsset(
884 userId, newArticle, assetCategoryIds, assetTagNames,
885 assetLinkEntryIds);
886
887 return newArticle;
888 }
889
890
897 @Override
898 @SystemEvent(
899 action = SystemEventConstants.ACTION_SKIP, send = false)
900 public JournalArticle deleteArticle(JournalArticle article)
901 throws PortalException, SystemException {
902
903 return journalArticleLocalService.deleteArticle(
904 article, StringPool.BLANK, null);
905 }
906
907
921 @Indexable(type = IndexableType.DELETE)
922 @Override
923 @SystemEvent(
924 action = SystemEventConstants.ACTION_SKIP, send = false)
925 public JournalArticle deleteArticle(
926 JournalArticle article, String articleURL,
927 ServiceContext serviceContext)
928 throws PortalException, SystemException {
929
930 JournalArticleResource articleResource =
931 journalArticleResourceLocalService.fetchArticleResource(
932 article.getGroupId(), article.getArticleId());
933
934 if (article.isApproved() &&
935 isLatestVersion(
936 article.getGroupId(), article.getArticleId(),
937 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
938
939 updatePreviousApprovedArticle(article);
940 }
941
942
943
944 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
945 PortletPreferences preferences =
946 ServiceContextUtil.getPortletPreferences(serviceContext);
947
948 if ((preferences != null) && !article.isApproved() &&
949 isLatestVersion(
950 article.getGroupId(), article.getArticleId(),
951 article.getVersion())) {
952
953 articleURL = buildArticleURL(
954 articleURL, article.getGroupId(), article.getFolderId(),
955 article.getArticleId());
956
957 sendEmail(
958 article, articleURL, preferences, "denied", serviceContext);
959 }
960 }
961
962
963
964 String articleId = article.getArticleId();
965
966 if (article.isInTrash()) {
967 articleId = TrashUtil.getOriginalTitle(articleId);
968 }
969
970 journalArticleImageLocalService.deleteImages(
971 article.getGroupId(), articleId, article.getVersion());
972
973
974
975 expandoRowLocalService.deleteRows(article.getId());
976
977
978
979 if (article.isInTrash()) {
980 TrashEntry trashEntry = article.getTrashEntry();
981
982 if (trashEntry != null) {
983 trashVersionLocalService.deleteTrashVersion(
984 trashEntry.getEntryId(), JournalArticle.class.getName(),
985 article.getId());
986 }
987 }
988
989
990
991 if (!article.isDraft()) {
992 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
993 article.getCompanyId(), article.getGroupId(),
994 JournalArticle.class.getName(), article.getId());
995 }
996
997 int articlesCount = journalArticlePersistence.countByG_A(
998 article.getGroupId(), article.getArticleId());
999
1000 if (articlesCount == 1) {
1001
1002
1003
1004 subscriptionLocalService.deleteSubscriptions(
1005 article.getCompanyId(), JournalArticle.class.getName(),
1006 article.getResourcePrimKey());
1007
1008
1009
1010 ratingsStatsLocalService.deleteStats(
1011 JournalArticle.class.getName(), article.getResourcePrimKey());
1012
1013
1014
1015 mbMessageLocalService.deleteDiscussionMessages(
1016 JournalArticle.class.getName(), article.getResourcePrimKey());
1017
1018
1019
1020 assetEntryLocalService.deleteEntry(
1021 JournalArticle.class.getName(), article.getResourcePrimKey());
1022
1023
1024
1025 journalContentSearchLocalService.deleteArticleContentSearches(
1026 article.getGroupId(), article.getArticleId());
1027
1028
1029
1030 imageLocalService.deleteImage(article.getSmallImageId());
1031
1032
1033
1034 trashEntryLocalService.deleteEntry(
1035 JournalArticle.class.getName(), article.getResourcePrimKey());
1036
1037
1038
1039 resourceLocalService.deleteResource(
1040 article.getCompanyId(), JournalArticle.class.getName(),
1041 ResourceConstants.SCOPE_INDIVIDUAL,
1042 article.getResourcePrimKey());
1043
1044
1045
1046 if (articleResource != null) {
1047 journalArticleResourceLocalService.deleteJournalArticleResource(
1048 articleResource);
1049 }
1050 }
1051
1052
1053
1054 journalArticlePersistence.remove(article);
1055
1056
1057
1058 if (articleResource != null) {
1059 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1060
1061 extraDataJSONObject.put("version", article.getVersion());
1062
1063 systemEventLocalService.addSystemEvent(
1064 0, article.getGroupId(), article.getModelClassName(),
1065 article.getPrimaryKey(), articleResource.getUuid(), null,
1066 SystemEventConstants.TYPE_DELETE,
1067 extraDataJSONObject.toString());
1068 }
1069
1070 return article;
1071 }
1072
1073
1089 @Override
1090 public JournalArticle deleteArticle(
1091 long groupId, String articleId, double version, String articleURL,
1092 ServiceContext serviceContext)
1093 throws PortalException, SystemException {
1094
1095 JournalArticle article = journalArticlePersistence.findByG_A_V(
1096 groupId, articleId, version);
1097
1098 return journalArticleLocalService.deleteArticle(
1099 article, articleURL, serviceContext);
1100 }
1101
1102
1115 @Override
1116 public void deleteArticle(
1117 long groupId, String articleId, ServiceContext serviceContext)
1118 throws PortalException, SystemException {
1119
1120 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1121
1122 JournalArticleResource articleResource =
1123 journalArticleResourceLocalService.fetchArticleResource(
1124 groupId, articleId);
1125
1126 try {
1127 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1128 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1129 new ArticleVersionComparator(true));
1130
1131 for (JournalArticle article : articles) {
1132 journalArticleLocalService.deleteArticle(
1133 article, null, serviceContext);
1134 }
1135 }
1136 finally {
1137 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1138 }
1139
1140 if (articleResource != null) {
1141 systemEventLocalService.addSystemEvent(
1142 0, groupId, JournalArticle.class.getName(),
1143 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1144 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1145 }
1146 }
1147
1148
1155 @Override
1156 public void deleteArticles(long groupId)
1157 throws PortalException, SystemException {
1158
1159 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1160
1161 List<JournalArticleResource> articleResources =
1162 new ArrayList<JournalArticleResource>();
1163
1164 try {
1165 JournalArticleResource articleResource = null;
1166
1167 for (JournalArticle article :
1168 journalArticlePersistence.findByGroupId(groupId)) {
1169
1170 if ((articleResource == null) ||
1171 (articleResource.getPrimaryKey() !=
1172 article.getResourcePrimKey())) {
1173
1174 articleResource =
1175 journalArticleResourceLocalService.getArticleResource(
1176 article.getResourcePrimKey());
1177
1178 articleResources.add(articleResource);
1179 }
1180
1181 journalArticleLocalService.deleteArticle(article, null, null);
1182 }
1183 }
1184 finally {
1185 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1186 }
1187
1188 for (JournalArticleResource articleResource : articleResources) {
1189 systemEventLocalService.addSystemEvent(
1190 0, groupId, JournalArticle.class.getName(),
1191 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1192 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1193 }
1194 }
1195
1196
1205 @Override
1206 public void deleteArticles(long groupId, long folderId)
1207 throws PortalException, SystemException {
1208
1209 deleteArticles(groupId, folderId, true);
1210 }
1211
1212
1223 @Override
1224 public void deleteArticles(
1225 long groupId, long folderId, boolean includeTrashedEntries)
1226 throws PortalException, SystemException {
1227
1228 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1229
1230 List<JournalArticleResource> articleResources =
1231 new ArrayList<JournalArticleResource>();
1232
1233 try {
1234 JournalArticleResource articleResource = null;
1235
1236 for (JournalArticle article :
1237 journalArticlePersistence.findByG_F(groupId, folderId)) {
1238
1239 if ((articleResource == null) ||
1240 (articleResource.getPrimaryKey() !=
1241 article.getResourcePrimKey())) {
1242
1243 articleResource =
1244 journalArticleResourceLocalService.getArticleResource(
1245 article.getResourcePrimKey());
1246
1247 articleResources.add(articleResource);
1248 }
1249
1250 if (includeTrashedEntries || !article.isInTrashExplicitly()) {
1251 journalArticleLocalService.deleteArticle(
1252 article, null, null);
1253 }
1254 else {
1255 articleResources.remove(articleResource);
1256 }
1257 }
1258 }
1259 finally {
1260 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1261 }
1262
1263 for (JournalArticleResource articleResource : articleResources) {
1264 systemEventLocalService.addSystemEvent(
1265 0, groupId, JournalArticle.class.getName(),
1266 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1267 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1268 }
1269 }
1270
1271 @Override
1272 public void deleteArticles(long groupId, String className, long classPK)
1273 throws PortalException, SystemException {
1274
1275 long classNameId = PortalUtil.getClassNameId(className);
1276
1277 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1278 groupId, classNameId, classPK);
1279
1280 for (JournalArticle article : articles) {
1281 journalArticleLocalService.deleteArticle(article, null, null);
1282 }
1283 }
1284
1285
1294 @Override
1295 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
1296 throws SystemException {
1297
1298 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1299 groupId, layoutUuid);
1300
1301 for (JournalArticle article : articles) {
1302 article.setLayoutUuid(StringPool.BLANK);
1303
1304 journalArticlePersistence.update(article);
1305 }
1306 }
1307
1308
1331 @Indexable(type = IndexableType.REINDEX)
1332 @Override
1333 public JournalArticle expireArticle(
1334 long userId, long groupId, String articleId, double version,
1335 String articleURL, ServiceContext serviceContext)
1336 throws PortalException, SystemException {
1337
1338 return updateStatus(
1339 userId, groupId, articleId, version,
1340 WorkflowConstants.STATUS_EXPIRED, articleURL,
1341 new HashMap<String, Serializable>(), serviceContext);
1342 }
1343
1344
1367 @Override
1368 public void expireArticle(
1369 long userId, long groupId, String articleId, String articleURL,
1370 ServiceContext serviceContext)
1371 throws PortalException, SystemException {
1372
1373 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1374 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1375 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1376 new ArticleVersionComparator(true));
1377
1378 for (JournalArticle article : articles) {
1379 journalArticleLocalService.expireArticle(
1380 userId, groupId, article.getArticleId(),
1381 article.getVersion(), articleURL, serviceContext);
1382 }
1383 }
1384 else {
1385 JournalArticle article = getLatestArticle(
1386 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1387
1388 journalArticleLocalService.expireArticle(
1389 userId, groupId, article.getArticleId(), article.getVersion(),
1390 articleURL, serviceContext);
1391 }
1392 }
1393
1394 @Override
1395 public JournalArticle fetchArticle(long groupId, String articleId)
1396 throws SystemException {
1397
1398
1399
1400
1401 JournalArticle article = fetchLatestArticle(
1402 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1403
1404 if (article != null) {
1405 return article;
1406 }
1407
1408 return fetchLatestArticle(
1409 groupId, articleId, WorkflowConstants.STATUS_ANY);
1410 }
1411
1412
1423 @Override
1424 public JournalArticle fetchArticle(
1425 long groupId, String articleId, double version)
1426 throws SystemException {
1427
1428 return journalArticlePersistence.fetchByG_A_V(
1429 groupId, articleId, version);
1430 }
1431
1432 @Override
1433 public JournalArticle fetchArticleByUrlTitle(long groupId, String urlTitle)
1434 throws SystemException {
1435
1436 JournalArticle article = fetchLatestArticleByUrlTitle(
1437 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1438
1439 if (article != null) {
1440 return article;
1441 }
1442
1443 return fetchLatestArticleByUrlTitle(
1444 groupId, urlTitle, WorkflowConstants.STATUS_ANY);
1445 }
1446
1447 @Override
1448 public JournalArticle fetchDisplayArticle(long groupId, String articleId)
1449 throws SystemException {
1450
1451 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
1452 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1453
1454 if (articles.isEmpty()) {
1455 return null;
1456 }
1457
1458 Date now = new Date();
1459
1460 for (JournalArticle article : articles) {
1461 Date displayDate = article.getDisplayDate();
1462 Date expirationDate = article.getExpirationDate();
1463
1464 if (((displayDate == null) || displayDate.before(now)) &&
1465 ((expirationDate == null) || expirationDate.after(now))) {
1466
1467 return article;
1468 }
1469 }
1470
1471 return articles.get(0);
1472 }
1473
1474 @Override
1475 public JournalArticle fetchLatestArticle(long resourcePrimKey)
1476 throws SystemException {
1477
1478 return fetchLatestArticle(
1479 resourcePrimKey, WorkflowConstants.STATUS_ANY);
1480 }
1481
1482 @Override
1483 public JournalArticle fetchLatestArticle(long resourcePrimKey, int status)
1484 throws SystemException {
1485
1486 return fetchLatestArticle(resourcePrimKey, status, true);
1487 }
1488
1489 public JournalArticle fetchLatestArticle(
1490 long resourcePrimKey, int[] statuses)
1491 throws SystemException {
1492
1493 OrderByComparator orderByComparator = new ArticleVersionComparator();
1494
1495 List<JournalArticle> articles = journalArticlePersistence.findByR_ST(
1496 resourcePrimKey, statuses, 0, 1, orderByComparator);
1497
1498 if (!articles.isEmpty()) {
1499 return articles.get(0);
1500 }
1501
1502 return null;
1503 }
1504
1505 @Override
1506 public JournalArticle fetchLatestArticle(
1507 long resourcePrimKey, int status, boolean preferApproved)
1508 throws SystemException {
1509
1510 JournalArticle article = null;
1511
1512 OrderByComparator orderByComparator = new ArticleVersionComparator();
1513
1514 if (status == WorkflowConstants.STATUS_ANY) {
1515 if (preferApproved) {
1516 article = journalArticlePersistence.fetchByR_ST_First(
1517 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1518 orderByComparator);
1519 }
1520
1521 if (article == null) {
1522 article =
1523 journalArticlePersistence.fetchByResourcePrimKey_First(
1524 resourcePrimKey, orderByComparator);
1525 }
1526 }
1527 else {
1528 article = journalArticlePersistence.fetchByR_ST_First(
1529 resourcePrimKey, status, orderByComparator);
1530 }
1531
1532 return article;
1533 }
1534
1535 @Override
1536 public JournalArticle fetchLatestArticle(
1537 long groupId, String articleId, int status)
1538 throws SystemException {
1539
1540 OrderByComparator orderByComparator = new ArticleVersionComparator();
1541
1542 if (status == WorkflowConstants.STATUS_ANY) {
1543 return journalArticlePersistence.fetchByG_A_NotST_First(
1544 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
1545 orderByComparator);
1546 }
1547
1548 return journalArticlePersistence.fetchByG_A_ST_First(
1549 groupId, articleId, status, orderByComparator);
1550 }
1551
1552 @Override
1553 public JournalArticle fetchLatestArticleByUrlTitle(
1554 long groupId, String urlTitle, int status)
1555 throws SystemException {
1556
1557 List<JournalArticle> articles = null;
1558
1559 OrderByComparator orderByComparator = new ArticleVersionComparator();
1560
1561 if (status == WorkflowConstants.STATUS_ANY) {
1562 articles = journalArticlePersistence.findByG_UT(
1563 groupId, urlTitle, 0, 1, orderByComparator);
1564 }
1565 else {
1566 articles = journalArticlePersistence.findByG_UT_ST(
1567 groupId, urlTitle, status, 0, 1, orderByComparator);
1568 }
1569
1570 if (articles.isEmpty()) {
1571 return null;
1572 }
1573
1574 return articles.get(0);
1575 }
1576
1577
1586 @Override
1587 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey)
1588 throws SystemException {
1589
1590 OrderByComparator orderByComparator = new ArticleVersionComparator();
1591
1592 int[] statuses = new int[] {
1593 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1594 };
1595
1596 List<JournalArticle> articles =
1597 journalArticlePersistence.findByR_I_S(
1598 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1599
1600 if (articles.isEmpty()) {
1601 return null;
1602 }
1603
1604 return articles.get(0);
1605 }
1606
1607
1616 @Override
1617 public JournalArticle getArticle(long id)
1618 throws PortalException, SystemException {
1619
1620 return journalArticlePersistence.findByPrimaryKey(id);
1621 }
1622
1623
1635 @Override
1636 public JournalArticle getArticle(long groupId, String articleId)
1637 throws PortalException, SystemException {
1638
1639
1640
1641
1642 JournalArticle article = fetchLatestArticle(
1643 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1644
1645 if (article != null) {
1646 return article;
1647 }
1648
1649 return getLatestArticle(
1650 groupId, articleId, WorkflowConstants.STATUS_ANY);
1651 }
1652
1653
1665 @Override
1666 public JournalArticle getArticle(
1667 long groupId, String articleId, double version)
1668 throws PortalException, SystemException {
1669
1670 return journalArticlePersistence.findByG_A_V(
1671 groupId, articleId, version);
1672 }
1673
1674
1692 @Override
1693 public JournalArticle getArticle(
1694 long groupId, String className, long classPK)
1695 throws PortalException, SystemException {
1696
1697 long classNameId = PortalUtil.getClassNameId(className);
1698
1699 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1700 groupId, classNameId, classPK);
1701
1702 if (articles.isEmpty()) {
1703 throw new NoSuchArticleException(
1704 "No approved JournalArticle exists with the key {groupId=" +
1705 groupId + ", className=" + className + ", classPK=" +
1706 classPK + "}");
1707 }
1708
1709 return articles.get(0);
1710 }
1711
1712
1723 @Override
1724 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1725 throws PortalException, SystemException {
1726
1727
1728
1729
1730 JournalArticle article = fetchLatestArticleByUrlTitle(
1731 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1732
1733 if (article != null) {
1734 return article;
1735 }
1736
1737 return getLatestArticleByUrlTitle(
1738 groupId, urlTitle, WorkflowConstants.STATUS_ANY);
1739 }
1740
1741
1758 @Override
1759 public String getArticleContent(
1760 JournalArticle article, String ddmTemplateKey, String viewMode,
1761 String languageId, ThemeDisplay themeDisplay)
1762 throws PortalException, SystemException {
1763
1764 JournalArticleDisplay articleDisplay = getArticleDisplay(
1765 article, ddmTemplateKey, viewMode, languageId, 1, null,
1766 themeDisplay);
1767
1768 if (articleDisplay == null) {
1769 return StringPool.BLANK;
1770 }
1771 else {
1772 return articleDisplay.getContent();
1773 }
1774 }
1775
1776
1795 @Override
1796 public String getArticleContent(
1797 long groupId, String articleId, double version, String viewMode,
1798 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1799 throws PortalException, SystemException {
1800
1801 JournalArticleDisplay articleDisplay = getArticleDisplay(
1802 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1803 themeDisplay);
1804
1805 if (articleDisplay == null) {
1806 return StringPool.BLANK;
1807 }
1808 else {
1809 return articleDisplay.getContent();
1810 }
1811 }
1812
1813
1827 @Override
1828 public String getArticleContent(
1829 long groupId, String articleId, double version, String viewMode,
1830 String languageId, ThemeDisplay themeDisplay)
1831 throws PortalException, SystemException {
1832
1833 return getArticleContent(
1834 groupId, articleId, version, viewMode, null, languageId,
1835 themeDisplay);
1836 }
1837
1838
1856 @Override
1857 public String getArticleContent(
1858 long groupId, String articleId, String viewMode,
1859 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1860 throws PortalException, SystemException {
1861
1862 JournalArticleDisplay articleDisplay = getArticleDisplay(
1863 groupId, articleId, ddmTemplateKey, viewMode, languageId,
1864 themeDisplay);
1865
1866 return articleDisplay.getContent();
1867 }
1868
1869
1882 @Override
1883 public String getArticleContent(
1884 long groupId, String articleId, String viewMode, String languageId,
1885 ThemeDisplay themeDisplay)
1886 throws PortalException, SystemException {
1887
1888 return getArticleContent(
1889 groupId, articleId, viewMode, null, languageId, themeDisplay);
1890 }
1891
1892
1916 @Override
1917 public JournalArticleDisplay getArticleDisplay(
1918 JournalArticle article, String ddmTemplateKey, String viewMode,
1919 String languageId, int page, String xmlRequest,
1920 ThemeDisplay themeDisplay)
1921 throws PortalException, SystemException {
1922
1923 String content = null;
1924
1925 if (page < 1) {
1926 page = 1;
1927 }
1928
1929 int numberOfPages = 1;
1930 boolean paginate = false;
1931 boolean pageFlow = false;
1932
1933 boolean cacheable = true;
1934
1935 if (Validator.isNull(xmlRequest)) {
1936 xmlRequest = "<request/>";
1937 }
1938
1939 Map<String, String> tokens = JournalUtil.getTokens(
1940 article.getGroupId(), themeDisplay, xmlRequest);
1941
1942 if ((themeDisplay == null) &&
1943 (xmlRequest.equals("<request/>") ||
1944 xmlRequest.equals("<request />"))) {
1945
1946 tokens.put("company_id", String.valueOf(article.getCompanyId()));
1947
1948 Group companyGroup = groupLocalService.getCompanyGroup(
1949 article.getCompanyId());
1950
1951 tokens.put(
1952 "article_group_id", String.valueOf(article.getGroupId()));
1953 tokens.put(
1954 "company_group_id", String.valueOf(companyGroup.getGroupId()));
1955
1956
1957
1958 tokens.put("group_id", String.valueOf(article.getGroupId()));
1959 }
1960
1961 tokens.put(
1962 "article_resource_pk",
1963 String.valueOf(article.getResourcePrimKey()));
1964
1965 String defaultDDMTemplateKey = article.getTemplateId();
1966
1967 if (article.isTemplateDriven()) {
1968 if (Validator.isNull(ddmTemplateKey)) {
1969 ddmTemplateKey = defaultDDMTemplateKey;
1970 }
1971
1972 tokens.put(
1973 TemplateConstants.CLASS_NAME_ID,
1974 String.valueOf(PortalUtil.getClassNameId(DDMStructure.class)));
1975 tokens.put("structure_id", article.getStructureId());
1976 tokens.put("template_id", ddmTemplateKey);
1977 }
1978
1979 String xml = article.getContent();
1980
1981 try {
1982 Document document = null;
1983
1984 Element rootElement = null;
1985
1986 if (article.isTemplateDriven()) {
1987 document = SAXReaderUtil.read(xml);
1988
1989 rootElement = document.getRootElement();
1990
1991 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1992
1993 List<Element> pages = rootElement.elements("page");
1994
1995 if (!pages.isEmpty()) {
1996 pageFlow = true;
1997
1998 String targetPage = requestDocument.valueOf(
1999 "/request/parameters/parameter[name='targetPage']/" +
2000 "value");
2001
2002 Element pageElement = null;
2003
2004 if (Validator.isNotNull(targetPage)) {
2005 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
2006
2007 XPath xPathSelector = SAXReaderUtil.createXPath(
2008 "/root/page[@id = " + targetPage + "]");
2009
2010 pageElement = (Element)xPathSelector.selectSingleNode(
2011 document);
2012 }
2013
2014 if (pageElement != null) {
2015 document = SAXReaderUtil.createDocument(pageElement);
2016
2017 rootElement = document.getRootElement();
2018
2019 numberOfPages = pages.size();
2020 }
2021 else {
2022 if (page > pages.size()) {
2023 page = 1;
2024 }
2025
2026 pageElement = pages.get(page - 1);
2027
2028 document = SAXReaderUtil.createDocument(pageElement);
2029
2030 rootElement = document.getRootElement();
2031
2032 numberOfPages = pages.size();
2033 paginate = true;
2034 }
2035 }
2036
2037 rootElement.add(requestDocument.getRootElement().createCopy());
2038
2039 JournalUtil.addAllReservedEls(
2040 rootElement, tokens, article, languageId, themeDisplay);
2041
2042 xml = DDMXMLUtil.formatXML(document);
2043 }
2044 }
2045 catch (DocumentException de) {
2046 throw new SystemException(de);
2047 }
2048
2049 try {
2050 if (_log.isDebugEnabled()) {
2051 _log.debug(
2052 "Transforming " + article.getArticleId() + " " +
2053 article.getVersion() + " " + languageId);
2054 }
2055
2056 String script = null;
2057 String langType = null;
2058
2059 if (article.isTemplateDriven()) {
2060
2061
2062
2063
2064
2065
2066
2067 DDMTemplate ddmTemplate = null;
2068
2069 try {
2070 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
2071 PortalUtil.getSiteGroupId(article.getGroupId()),
2072 PortalUtil.getClassNameId(DDMStructure.class),
2073 ddmTemplateKey);
2074 }
2075 catch (NoSuchTemplateException nste1) {
2076 try {
2077 Group companyGroup = groupLocalService.getCompanyGroup(
2078 article.getCompanyId());
2079
2080 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
2081 companyGroup.getGroupId(),
2082 PortalUtil.getClassNameId(DDMStructure.class),
2083 ddmTemplateKey);
2084
2085 tokens.put(
2086 "company_group_id",
2087 String.valueOf(companyGroup.getGroupId()));
2088 }
2089 catch (NoSuchTemplateException nste2) {
2090 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
2091 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
2092 PortalUtil.getSiteGroupId(article.getGroupId()),
2093 PortalUtil.getClassNameId(DDMStructure.class),
2094 defaultDDMTemplateKey);
2095 }
2096 else {
2097 throw nste1;
2098 }
2099 }
2100 }
2101
2102 script = ddmTemplate.getScript();
2103 langType = ddmTemplate.getLanguage();
2104 cacheable = ddmTemplate.isCacheable();
2105 }
2106
2107 content = JournalUtil.transform(
2108 themeDisplay, tokens, viewMode, languageId, xml, script,
2109 langType);
2110
2111 if (!pageFlow) {
2112 String[] pieces = StringUtil.split(
2113 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
2114
2115 if (pieces.length > 1) {
2116 if (page > pieces.length) {
2117 page = 1;
2118 }
2119
2120 content = pieces[page - 1];
2121 numberOfPages = pieces.length;
2122 paginate = true;
2123 }
2124 }
2125 }
2126 catch (Exception e) {
2127 throw new SystemException(e);
2128 }
2129
2130 return new JournalArticleDisplayImpl(
2131 article.getCompanyId(), article.getId(),
2132 article.getResourcePrimKey(), article.getGroupId(),
2133 article.getUserId(), article.getArticleId(), article.getVersion(),
2134 article.getTitle(languageId), article.getUrlTitle(),
2135 article.getDescription(languageId),
2136 article.getAvailableLanguageIds(), content, article.getType(),
2137 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
2138 article.getSmallImageId(), article.getSmallImageURL(),
2139 numberOfPages, page, paginate, cacheable);
2140 }
2141
2142
2169 @Override
2170 public JournalArticleDisplay getArticleDisplay(
2171 long groupId, String articleId, double version,
2172 String ddmTemplateKey, String viewMode, String languageId, int page,
2173 String xmlRequest, ThemeDisplay themeDisplay)
2174 throws PortalException, SystemException {
2175
2176 Date now = new Date();
2177
2178 JournalArticle article = journalArticlePersistence.findByG_A_V(
2179 groupId, articleId, version);
2180
2181 if (article.isExpired()) {
2182 Date expirationDate = article.getExpirationDate();
2183
2184 if ((expirationDate != null) && expirationDate.before(now)) {
2185 return null;
2186 }
2187 }
2188
2189 Date displayDate = article.getDisplayDate();
2190
2191 if (displayDate.after(now)) {
2192 return null;
2193 }
2194
2195 return getArticleDisplay(
2196 article, ddmTemplateKey, viewMode, languageId, page, xmlRequest,
2197 themeDisplay);
2198 }
2199
2200
2224 @Override
2225 public JournalArticleDisplay getArticleDisplay(
2226 long groupId, String articleId, double version,
2227 String ddmTemplateKey, String viewMode, String languageId,
2228 ThemeDisplay themeDisplay)
2229 throws PortalException, SystemException {
2230
2231 return getArticleDisplay(
2232 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2233 1, null, themeDisplay);
2234 }
2235
2236
2258 @Override
2259 public JournalArticleDisplay getArticleDisplay(
2260 long groupId, String articleId, String viewMode, String languageId,
2261 int page, String xmlRequest, ThemeDisplay themeDisplay)
2262 throws PortalException, SystemException {
2263
2264 return getArticleDisplay(
2265 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
2266 themeDisplay);
2267 }
2268
2269
2296 @Override
2297 public JournalArticleDisplay getArticleDisplay(
2298 long groupId, String articleId, String ddmTemplateKey,
2299 String viewMode, String languageId, int page, String xmlRequest,
2300 ThemeDisplay themeDisplay)
2301 throws PortalException, SystemException {
2302
2303 JournalArticle article = getDisplayArticle(groupId, articleId);
2304
2305 return getArticleDisplay(
2306 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2307 languageId, page, xmlRequest, themeDisplay);
2308 }
2309
2310
2333 @Override
2334 public JournalArticleDisplay getArticleDisplay(
2335 long groupId, String articleId, String ddmTemplateKey,
2336 String viewMode, String languageId, ThemeDisplay themeDisplay)
2337 throws PortalException, SystemException {
2338
2339 JournalArticle article = getDisplayArticle(groupId, articleId);
2340
2341 return getArticleDisplay(
2342 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2343 languageId, themeDisplay);
2344 }
2345
2346
2364 @Override
2365 public JournalArticleDisplay getArticleDisplay(
2366 long groupId, String articleId, String viewMode, String languageId,
2367 ThemeDisplay themeDisplay)
2368 throws PortalException, SystemException {
2369
2370 return getArticleDisplay(
2371 groupId, articleId, null, viewMode, languageId, themeDisplay);
2372 }
2373
2374
2380 @Override
2381 public List<JournalArticle> getArticles() throws SystemException {
2382 return journalArticlePersistence.findAll();
2383 }
2384
2385
2392 @Override
2393 public List<JournalArticle> getArticles(long groupId)
2394 throws SystemException {
2395
2396 return journalArticlePersistence.findByGroupId(groupId);
2397 }
2398
2399
2419 @Override
2420 public List<JournalArticle> getArticles(long groupId, int start, int end)
2421 throws SystemException {
2422
2423 return journalArticlePersistence.findByGroupId(groupId, start, end);
2424 }
2425
2426
2449 @Override
2450 public List<JournalArticle> getArticles(
2451 long groupId, int start, int end, OrderByComparator obc)
2452 throws SystemException {
2453
2454 return journalArticlePersistence.findByGroupId(
2455 groupId, start, end, obc);
2456 }
2457
2458
2466 @Override
2467 public List<JournalArticle> getArticles(long groupId, long folderId)
2468 throws SystemException {
2469
2470 return journalArticlePersistence.findByG_F(groupId, folderId);
2471 }
2472
2473
2495 @Override
2496 public List<JournalArticle> getArticles(
2497 long groupId, long folderId, int start, int end)
2498 throws SystemException {
2499
2500 return journalArticlePersistence.findByG_F(
2501 groupId, folderId, start, end);
2502 }
2503
2504 @Override
2505 public List<JournalArticle> getArticles(
2506 long groupId, long folderId, int status, int start, int end)
2507 throws SystemException {
2508
2509 return journalArticlePersistence.findByG_F_ST(
2510 groupId, folderId, status, start, end);
2511 }
2512
2513
2538 @Override
2539 public List<JournalArticle> getArticles(
2540 long groupId, long folderId, int start, int end,
2541 OrderByComparator orderByComparator)
2542 throws SystemException {
2543
2544 return journalArticlePersistence.findByG_F(
2545 groupId, folderId, start, end, orderByComparator);
2546 }
2547
2548
2556 @Override
2557 public List<JournalArticle> getArticles(long groupId, String articleId)
2558 throws SystemException {
2559
2560 return journalArticlePersistence.findByG_A(groupId, articleId);
2561 }
2562
2563 @Override
2564 public List<JournalArticle> getArticles(
2565 long groupId, String articleId, int start, int end,
2566 OrderByComparator orderByComparator)
2567 throws SystemException {
2568
2569 return journalArticlePersistence.findByG_A(
2570 groupId, articleId, start, end, orderByComparator);
2571 }
2572
2573 @Override
2574 public List<JournalArticle> getArticlesByResourcePrimKey(
2575 long resourcePrimKey)
2576 throws SystemException {
2577
2578 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2579 }
2580
2581
2589 @Override
2590 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
2591 throws SystemException {
2592
2593 return journalArticlePersistence.findBySmallImageId(smallImageId);
2594 }
2595
2596
2603 @Override
2604 public int getArticlesCount(long groupId) throws SystemException {
2605 return journalArticlePersistence.countByGroupId(groupId);
2606 }
2607
2608
2616 @Override
2617 public int getArticlesCount(long groupId, long folderId)
2618 throws SystemException {
2619
2620 return journalArticlePersistence.countByG_F(groupId, folderId);
2621 }
2622
2623 @Override
2624 public int getArticlesCount(long groupId, long folderId, int status)
2625 throws SystemException {
2626
2627 return journalArticlePersistence.countByG_F_ST(
2628 groupId, folderId, status);
2629 }
2630
2631 @Override
2632 public int getArticlesCount(long groupId, String articleId)
2633 throws SystemException {
2634
2635 return journalArticlePersistence.countByG_A(groupId, articleId);
2636 }
2637
2638
2663 @Override
2664 public List<JournalArticle> getCompanyArticles(
2665 long companyId, double version, int status, int start, int end)
2666 throws SystemException {
2667
2668 if (status == WorkflowConstants.STATUS_ANY) {
2669 return journalArticlePersistence.findByC_V(
2670 companyId, version, start, end, new ArticleIDComparator(true));
2671 }
2672 else {
2673 return journalArticlePersistence.findByC_V_ST(
2674 companyId, version, status, start, end,
2675 new ArticleIDComparator(true));
2676 }
2677 }
2678
2679
2703 @Override
2704 public List<JournalArticle> getCompanyArticles(
2705 long companyId, int status, int start, int end)
2706 throws SystemException {
2707
2708 if (status == WorkflowConstants.STATUS_ANY) {
2709 return journalArticlePersistence.findByCompanyId(
2710 companyId, start, end, new ArticleIDComparator(true));
2711 }
2712 else {
2713 return journalArticlePersistence.findByC_ST(
2714 companyId, status, start, end, new ArticleIDComparator(true));
2715 }
2716 }
2717
2718
2743 @Override
2744 public int getCompanyArticlesCount(
2745 long companyId, double version, int status, int start, int end)
2746 throws SystemException {
2747
2748 if (status == WorkflowConstants.STATUS_ANY) {
2749 return journalArticlePersistence.countByC_V(companyId, version);
2750 }
2751 else {
2752 return journalArticlePersistence.countByC_V_ST(
2753 companyId, version, status);
2754 }
2755 }
2756
2757
2768 @Override
2769 public int getCompanyArticlesCount(long companyId, int status)
2770 throws SystemException {
2771
2772 if (status == WorkflowConstants.STATUS_ANY) {
2773 return journalArticlePersistence.countByCompanyId(companyId);
2774 }
2775 else {
2776 return journalArticlePersistence.countByC_ST(companyId, status);
2777 }
2778 }
2779
2780
2793 @Override
2794 public JournalArticle getDisplayArticle(long groupId, String articleId)
2795 throws PortalException, SystemException {
2796
2797 JournalArticle article = fetchDisplayArticle(groupId, articleId);
2798
2799 if (article == null) {
2800 throw new NoSuchArticleException(
2801 "No approved JournalArticle exists with the key {groupId=" +
2802 groupId + ", " + "articleId=" + articleId + "}");
2803 }
2804
2805 return article;
2806 }
2807
2808
2821 @Override
2822 public JournalArticle getDisplayArticleByUrlTitle(
2823 long groupId, String urlTitle)
2824 throws PortalException, SystemException {
2825
2826 List<JournalArticle> articles = null;
2827
2828 OrderByComparator orderByComparator = new ArticleVersionComparator();
2829
2830 articles = journalArticlePersistence.findByG_UT_ST(
2831 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2832 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2833
2834 if (articles.isEmpty()) {
2835 throw new NoSuchArticleException(
2836 "No JournalArticle exists with the key {groupId=" + groupId +
2837 ", urlTitle=" + urlTitle + "}");
2838 }
2839
2840 Date now = new Date();
2841
2842 for (JournalArticle article : articles) {
2843 Date displayDate = article.getDisplayDate();
2844 Date expirationDate = article.getExpirationDate();
2845
2846 if (((displayDate != null) && displayDate.before(now)) &&
2847 ((expirationDate == null) || expirationDate.after(now)) ) {
2848
2849 return article;
2850 }
2851 }
2852
2853 return articles.get(0);
2854 }
2855
2856 @Override
2857 public List<JournalArticle> getIndexableArticlesByDDMStructureKey(
2858 String[] ddmStructureKeys)
2859 throws SystemException {
2860
2861 if (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
2862 return getStructureArticles(ddmStructureKeys);
2863 }
2864
2865 QueryDefinition approvedQueryDefinition =
2866 new QueryDefinition(
2867 WorkflowConstants.STATUS_APPROVED, QueryUtil.ALL_POS,
2868 QueryUtil.ALL_POS, new ArticleVersionComparator());
2869
2870 List<JournalArticle> articles = new ArrayList<JournalArticle>();
2871
2872 articles.addAll(
2873 journalArticleFinder.findByG_C_S(
2874 0, JournalArticleConstants.CLASSNAME_ID_DEFAULT,
2875 ddmStructureKeys, approvedQueryDefinition));
2876
2877 QueryDefinition trashQueryDefinition =
2878 new QueryDefinition(
2879 WorkflowConstants.STATUS_IN_TRASH, QueryUtil.ALL_POS,
2880 QueryUtil.ALL_POS, new ArticleVersionComparator());
2881
2882 articles.addAll(
2883 journalArticleFinder.findByG_C_S(
2884 0, JournalArticleConstants.CLASSNAME_ID_DEFAULT,
2885 ddmStructureKeys, trashQueryDefinition));
2886
2887 return articles;
2888 }
2889
2890 @Override
2891 public List<JournalArticle> getIndexableArticlesByResourcePrimKey(
2892 long resourcePrimKey)
2893 throws SystemException {
2894
2895 return journalArticlePersistence.findByR_I(resourcePrimKey, true);
2896 }
2897
2898
2909 @Override
2910 public JournalArticle getLatestArticle(long resourcePrimKey)
2911 throws PortalException, SystemException {
2912
2913 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2914 }
2915
2916
2931 @Override
2932 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2933 throws PortalException, SystemException {
2934
2935 return getLatestArticle(resourcePrimKey, status, true);
2936 }
2937
2938
2958 @Override
2959 public JournalArticle getLatestArticle(
2960 long resourcePrimKey, int status, boolean preferApproved)
2961 throws PortalException, SystemException {
2962
2963 List<JournalArticle> articles = null;
2964
2965 OrderByComparator orderByComparator = new ArticleVersionComparator();
2966
2967 if (status == WorkflowConstants.STATUS_ANY) {
2968 if (preferApproved) {
2969 articles = journalArticlePersistence.findByR_ST(
2970 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2971 orderByComparator);
2972 }
2973
2974 if ((articles == null) || (articles.size() == 0)) {
2975 articles = journalArticlePersistence.findByResourcePrimKey(
2976 resourcePrimKey, 0, 1, orderByComparator);
2977 }
2978 }
2979 else {
2980 articles = journalArticlePersistence.findByR_ST(
2981 resourcePrimKey, status, 0, 1, orderByComparator);
2982 }
2983
2984 if (articles.isEmpty()) {
2985 throw new NoSuchArticleException(
2986 "No JournalArticle exists with the key {resourcePrimKey=" +
2987 resourcePrimKey + "}");
2988 }
2989
2990 return articles.get(0);
2991 }
2992
2993
3003 @Override
3004 public JournalArticle getLatestArticle(long groupId, String articleId)
3005 throws PortalException, SystemException {
3006
3007 return getLatestArticle(
3008 groupId, articleId, WorkflowConstants.STATUS_ANY);
3009 }
3010
3011
3025 @Override
3026 public JournalArticle getLatestArticle(
3027 long groupId, String articleId, int status)
3028 throws PortalException, SystemException {
3029
3030 return getFirstArticle(
3031 groupId, articleId, status, new ArticleVersionComparator());
3032 }
3033
3034
3052 @Override
3053 public JournalArticle getLatestArticle(
3054 long groupId, String className, long classPK)
3055 throws PortalException, SystemException {
3056
3057 long classNameId = PortalUtil.getClassNameId(className);
3058
3059 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
3060 groupId, classNameId, classPK, 0, 1,
3061 new ArticleVersionComparator());
3062
3063 if (articles.isEmpty()) {
3064 throw new NoSuchArticleException(
3065 "No JournalArticle exists with the key {groupId=" + groupId +
3066 ", className=" + className + ", classPK =" + classPK + "}");
3067 }
3068
3069 return articles.get(0);
3070 }
3071
3072
3086 @Override
3087 public JournalArticle getLatestArticleByUrlTitle(
3088 long groupId, String urlTitle, int status)
3089 throws PortalException, SystemException {
3090
3091 JournalArticle article = fetchLatestArticleByUrlTitle(
3092 groupId, urlTitle, status);
3093
3094 if (article == null) {
3095 throw new NoSuchArticleException(
3096 "No JournalArticle exists with the key {groupId=" + groupId +
3097 ", urlTitle=" + urlTitle + ", status=" + status + "}");
3098 }
3099
3100 return article;
3101 }
3102
3103
3114 @Override
3115 public double getLatestVersion(long groupId, String articleId)
3116 throws PortalException, SystemException {
3117
3118 JournalArticle article = getLatestArticle(groupId, articleId);
3119
3120 return article.getVersion();
3121 }
3122
3123
3137 @Override
3138 public double getLatestVersion(long groupId, String articleId, int status)
3139 throws PortalException, SystemException {
3140
3141 JournalArticle article = getLatestArticle(groupId, articleId, status);
3142
3143 return article.getVersion();
3144 }
3145
3146
3154 @Override
3155 public int getNotInTrashArticlesCount(long groupId, long folderId)
3156 throws SystemException {
3157
3158 QueryDefinition queryDefinition = new QueryDefinition(
3159 WorkflowConstants.STATUS_ANY);
3160
3161 List<Long> folderIds = new ArrayList<Long>();
3162
3163 folderIds.add(folderId);
3164
3165 return journalArticleFinder.countByG_F(
3166 groupId, folderIds, queryDefinition);
3167 }
3168
3169 @Override
3170 public JournalArticle getOldestArticle(long groupId, String articleId)
3171 throws PortalException, SystemException {
3172
3173 return getOldestArticle(
3174 groupId, articleId, WorkflowConstants.STATUS_ANY);
3175 }
3176
3177 @Override
3178 public JournalArticle getOldestArticle(
3179 long groupId, String articleId, int status)
3180 throws PortalException, SystemException {
3181
3182 return getFirstArticle(
3183 groupId, articleId, status, new ArticleVersionComparator(false));
3184 }
3185
3186
3196 @Override
3197 public List<JournalArticle> getStructureArticles(
3198 long groupId, String ddmStructureKey)
3199 throws SystemException {
3200
3201 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
3202 }
3203
3204
3229 @Override
3230 public List<JournalArticle> getStructureArticles(
3231 long groupId, String ddmStructureKey, int start, int end,
3232 OrderByComparator obc)
3233 throws SystemException {
3234
3235 return journalArticlePersistence.findByG_S(
3236 groupId, ddmStructureKey, start, end, obc);
3237 }
3238
3239 @Override
3240 public List<JournalArticle> getStructureArticles(String[] ddmStructureKeys)
3241 throws SystemException {
3242
3243 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
3244 }
3245
3246
3256 @Override
3257 public int getStructureArticlesCount(long groupId, String ddmStructureKey)
3258 throws SystemException {
3259
3260 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
3261 }
3262
3263
3271 @Override
3272 public int getStructureArticlesCount(String ddmStructureKey)
3273 throws SystemException {
3274
3275 return journalArticlePersistence.countByStructureId(ddmStructureKey);
3276 }
3277
3278
3289 @Override
3290 public List<JournalArticle> getTemplateArticles(
3291 long groupId, String ddmTemplateKey)
3292 throws SystemException {
3293
3294 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3295 }
3296
3297
3324 @Override
3325 public List<JournalArticle> getTemplateArticles(
3326 long groupId, String ddmTemplateKey, int start, int end,
3327 OrderByComparator obc)
3328 throws SystemException {
3329
3330 return journalArticlePersistence.findByG_T(
3331 groupId, ddmTemplateKey, start, end, obc);
3332 }
3333
3334
3346 @Override
3347 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey)
3348 throws SystemException {
3349
3350 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3351 }
3352
3353 @Override
3354 public String getUniqueUrlTitle(
3355 long groupId, String articleId, String urlTitle)
3356 throws PortalException, SystemException {
3357
3358 for (int i = 1;; i++) {
3359 JournalArticle article = fetchArticleByUrlTitle(groupId, urlTitle);
3360
3361 if ((article == null) || articleId.equals(article.getArticleId())) {
3362 break;
3363 }
3364 else {
3365 String suffix = StringPool.DASH + i;
3366
3367 String prefix = urlTitle;
3368
3369 if (urlTitle.length() > suffix.length()) {
3370 prefix = urlTitle.substring(
3371 0, urlTitle.length() - suffix.length());
3372 }
3373
3374 urlTitle = prefix + suffix;
3375 }
3376 }
3377
3378 return urlTitle;
3379 }
3380
3381
3390 @Override
3391 public boolean hasArticle(long groupId, String articleId)
3392 throws SystemException {
3393
3394 JournalArticle article = fetchArticle(groupId, articleId);
3395
3396 if (article != null) {
3397 return true;
3398 }
3399
3400 return false;
3401 }
3402
3403
3416 @Override
3417 public boolean isLatestVersion(
3418 long groupId, String articleId, double version)
3419 throws PortalException, SystemException {
3420
3421 if (getLatestVersion(groupId, articleId) == version) {
3422 return true;
3423 }
3424 else {
3425 return false;
3426 }
3427 }
3428
3429
3445 @Override
3446 public boolean isLatestVersion(
3447 long groupId, String articleId, double version, int status)
3448 throws PortalException, SystemException {
3449
3450 if (getLatestVersion(groupId, articleId, status) == version) {
3451 return true;
3452 }
3453 else {
3454 return false;
3455 }
3456 }
3457
3458
3471 @Indexable(type = IndexableType.REINDEX)
3472 @Override
3473 public JournalArticle moveArticle(
3474 long groupId, String articleId, long newFolderId)
3475 throws PortalException, SystemException {
3476
3477 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3478 groupId, articleId);
3479
3480 for (JournalArticle article : articles) {
3481 article.setFolderId(newFolderId);
3482 article.setModifiedDate(new Date());
3483 article.setTreePath(article.buildTreePath());
3484
3485 journalArticlePersistence.update(article);
3486 }
3487
3488 return getArticle(groupId, articleId);
3489 }
3490
3491
3514 @Indexable(type = IndexableType.REINDEX)
3515 @Override
3516 public JournalArticle moveArticleFromTrash(
3517 long userId, long groupId, JournalArticle article, long newFolderId,
3518 ServiceContext serviceContext)
3519 throws PortalException, SystemException {
3520
3521 if (article.isInTrashExplicitly()) {
3522 restoreArticleFromTrash(userId, article);
3523 }
3524 else {
3525
3526
3527
3528 TrashEntry trashEntry = article.getTrashEntry();
3529
3530 TrashVersion trashVersion =
3531 trashVersionLocalService.fetchVersion(
3532 trashEntry.getEntryId(), JournalArticle.class.getName(),
3533 article.getResourcePrimKey());
3534
3535 int status = WorkflowConstants.STATUS_APPROVED;
3536
3537 if (trashVersion != null) {
3538 status = trashVersion.getStatus();
3539 }
3540
3541 updateStatus(
3542 userId, article, status, null,
3543 new HashMap<String, Serializable>(), serviceContext);
3544
3545
3546
3547 if (trashVersion != null) {
3548 trashVersionLocalService.deleteTrashVersion(trashVersion);
3549 }
3550 }
3551
3552 return moveArticle(groupId, article.getArticleId(), newFolderId);
3553 }
3554
3555
3568 @Indexable(type = IndexableType.REINDEX)
3569 @Override
3570 public JournalArticle moveArticleToTrash(
3571 long userId, JournalArticle article)
3572 throws PortalException, SystemException {
3573
3574
3575
3576 article.setModifiedDate(new Date());
3577
3578 int oldStatus = article.getStatus();
3579
3580 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3581 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3582 }
3583
3584 journalArticlePersistence.update(article);
3585
3586 List<JournalArticle> articleVersions =
3587 journalArticlePersistence.findByG_A(
3588 article.getGroupId(), article.getArticleId());
3589
3590 articleVersions = ListUtil.sort(
3591 articleVersions, new ArticleVersionComparator());
3592
3593 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
3594 new ArrayList<ObjectValuePair<Long, Integer>>();
3595
3596 if ((articleVersions != null) && !articleVersions.isEmpty()) {
3597 articleVersionStatusOVPs = getArticleVersionStatuses(
3598 articleVersions);
3599 }
3600
3601 article = updateStatus(
3602 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3603 new HashMap<String, Serializable>(), new ServiceContext());
3604
3605
3606
3607 JournalArticleResource articleResource =
3608 journalArticleResourceLocalService.getArticleResource(
3609 article.getResourcePrimKey());
3610
3611 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
3612
3613 typeSettingsProperties.put("title", article.getArticleId());
3614
3615 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
3616 userId, article.getGroupId(), JournalArticle.class.getName(),
3617 article.getResourcePrimKey(), articleResource.getUuid(), null,
3618 oldStatus, articleVersionStatusOVPs, typeSettingsProperties);
3619
3620 String trashArticleId = TrashUtil.getTrashTitle(
3621 trashEntry.getEntryId());
3622
3623 for (JournalArticle articleVersion : articleVersions) {
3624 articleVersion.setArticleId(trashArticleId);
3625 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
3626
3627 journalArticlePersistence.update(articleVersion);
3628 }
3629
3630 articleResource.setArticleId(trashArticleId);
3631
3632 journalArticleResourcePersistence.update(articleResource);
3633
3634 article.setArticleId(trashArticleId);
3635
3636 article = journalArticlePersistence.update(article);
3637
3638
3639
3640 assetEntryLocalService.updateVisible(
3641 JournalArticle.class.getName(), article.getResourcePrimKey(),
3642 false);
3643
3644
3645
3646 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
3647 mbMessageLocalService.moveDiscussionToTrash(
3648 JournalArticle.class.getName(), article.getResourcePrimKey());
3649 }
3650
3651
3652
3653 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3654
3655 extraDataJSONObject.put("title", article.getTitle());
3656
3657 socialActivityLocalService.addActivity(
3658 userId, article.getGroupId(), JournalArticle.class.getName(),
3659 article.getResourcePrimKey(),
3660 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3661 extraDataJSONObject.toString(), 0);
3662
3663 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3664 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3665 article.getCompanyId(), article.getGroupId(),
3666 JournalArticle.class.getName(), article.getId());
3667 }
3668
3669 return article;
3670 }
3671
3672
3686 @Override
3687 public JournalArticle moveArticleToTrash(
3688 long userId, long groupId, String articleId)
3689 throws PortalException, SystemException {
3690
3691 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3692 groupId, articleId, 0, 1, new ArticleVersionComparator());
3693
3694 if (!articles.isEmpty()) {
3695 return journalArticleLocalService.moveArticleToTrash(
3696 userId, articles.get(0));
3697 }
3698
3699 return null;
3700 }
3701
3702 @Override
3703 public void rebuildTree(long companyId)
3704 throws PortalException, SystemException {
3705 journalFolderLocalService.rebuildTree(companyId);
3706 }
3707
3708
3721 @Indexable(type = IndexableType.REINDEX)
3722 @Override
3723 public JournalArticle removeArticleLocale(
3724 long groupId, String articleId, double version, String languageId)
3725 throws PortalException, SystemException {
3726
3727 JournalArticle article = journalArticlePersistence.findByG_A_V(
3728 groupId, articleId, version);
3729
3730 String title = article.getTitle();
3731
3732 title = LocalizationUtil.removeLocalization(
3733 title, "static-content", languageId, true);
3734
3735 article.setTitle(title);
3736
3737 String description = article.getDescription();
3738
3739 description = LocalizationUtil.removeLocalization(
3740 description, "static-content", languageId, true);
3741
3742 article.setDescription(description);
3743
3744 String content = article.getContent();
3745
3746 if (article.isTemplateDriven()) {
3747 content = JournalUtil.removeArticleLocale(content, languageId);
3748 }
3749 else {
3750 content = LocalizationUtil.removeLocalization(
3751 content, "static-content", languageId, true);
3752 }
3753
3754 article.setContent(content);
3755
3756 article.setModifiedDate(new Date());
3757
3758 journalArticlePersistence.update(article);
3759
3760 return article;
3761 }
3762
3763
3775 @Indexable(type = IndexableType.REINDEX)
3776 @Override
3777 public JournalArticle restoreArticleFromTrash(
3778 long userId, JournalArticle article)
3779 throws PortalException, SystemException {
3780
3781
3782
3783 String trashArticleId = TrashUtil.getOriginalTitle(
3784 article.getArticleId());
3785
3786 List<JournalArticle> articleVersions =
3787 journalArticlePersistence.findByG_A(
3788 article.getGroupId(), article.getArticleId());
3789
3790 for (JournalArticle articleVersion : articleVersions) {
3791 articleVersion.setArticleId(trashArticleId);
3792
3793 journalArticlePersistence.update(articleVersion);
3794 }
3795
3796 article.setArticleId(trashArticleId);
3797 article.setModifiedDate(new Date());
3798
3799 journalArticlePersistence.update(article);
3800
3801 JournalArticleResource articleResource =
3802 journalArticleResourcePersistence.fetchByPrimaryKey(
3803 article.getResourcePrimKey());
3804
3805 articleResource.setArticleId(trashArticleId);
3806
3807 journalArticleResourcePersistence.update(articleResource);
3808
3809 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3810 JournalArticle.class.getName(), article.getResourcePrimKey());
3811
3812 ServiceContext serviceContext = new ServiceContext();
3813
3814 serviceContext.setScopeGroupId(article.getGroupId());
3815
3816 updateStatus(
3817 userId, article, trashEntry.getStatus(), null,
3818 new HashMap<String, Serializable>(), serviceContext);
3819
3820
3821
3822 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3823 trashEntry.getEntryId());
3824
3825 boolean visible = false;
3826
3827 for (TrashVersion trashVersion : trashVersions) {
3828 JournalArticle trashArticleVersion =
3829 journalArticlePersistence.findByPrimaryKey(
3830 trashVersion.getClassPK());
3831
3832 trashArticleVersion.setStatus(trashVersion.getStatus());
3833
3834 if (trashVersion.getStatus() == WorkflowConstants.STATUS_APPROVED) {
3835 visible = true;
3836 }
3837
3838 journalArticlePersistence.update(trashArticleVersion);
3839 }
3840
3841 trashEntryLocalService.deleteEntry(
3842 JournalArticle.class.getName(), article.getResourcePrimKey());
3843
3844 if (visible) {
3845 assetEntryLocalService.updateVisible(
3846 JournalArticle.class.getName(), article.getResourcePrimKey(),
3847 true);
3848 }
3849
3850
3851
3852 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
3853 mbMessageLocalService.restoreDiscussionFromTrash(
3854 JournalArticle.class.getName(), article.getResourcePrimKey());
3855 }
3856
3857
3858
3859 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3860
3861 extraDataJSONObject.put("title", article.getTitle());
3862
3863 socialActivityLocalService.addActivity(
3864 userId, article.getGroupId(), JournalArticle.class.getName(),
3865 article.getResourcePrimKey(),
3866 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3867 extraDataJSONObject.toString(), 0);
3868
3869 return article;
3870 }
3871
3872 @Override
3873 public List<JournalArticle> search(
3874 long groupId, List<Long> folderIds, int status, int start, int end)
3875 throws SystemException {
3876
3877 QueryDefinition queryDefinition = new QueryDefinition(
3878 status, start, end, null);
3879
3880 return journalArticleFinder.findByG_F(
3881 groupId, folderIds, queryDefinition);
3882 }
3883
3884 @Override
3885 public List<JournalArticle> search(
3886 long groupId, long folderId, int status, int start, int end)
3887 throws SystemException {
3888
3889 List<Long> folderIds = new ArrayList<Long>();
3890
3891 folderIds.add(folderId);
3892
3893 return search(groupId, folderIds, status, start, end);
3894 }
3895
3896
3958 @Override
3959 public List<JournalArticle> search(
3960 long companyId, long groupId, List<Long> folderIds,
3961 long classNameId, String keywords, Double version, String type,
3962 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3963 Date displayDateLT, int status, Date reviewDate, int start, int end,
3964 OrderByComparator obc)
3965 throws SystemException {
3966
3967 return journalArticleFinder.findByKeywords(
3968 companyId, groupId, folderIds, classNameId, keywords, version, type,
3969 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3970 status, reviewDate, start, end, obc);
3971 }
3972
3973
4042 @Override
4043 public List<JournalArticle> search(
4044 long companyId, long groupId, List<Long> folderIds,
4045 long classNameId, String articleId, Double version, String title,
4046 String description, String content, String type,
4047 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4048 Date displayDateLT, int status, Date reviewDate,
4049 boolean andOperator, int start, int end, OrderByComparator obc)
4050 throws SystemException {
4051
4052 QueryDefinition queryDefinition = new QueryDefinition(
4053 status, start, end, obc);
4054
4055 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4056 companyId, groupId, folderIds, classNameId, articleId, version,
4057 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4058 displayDateGT, displayDateLT, reviewDate, andOperator,
4059 queryDefinition);
4060 }
4061
4062
4128 @Override
4129 public List<JournalArticle> search(
4130 long companyId, long groupId, List<Long> folderIds,
4131 long classNameId, String articleId, Double version, String title,
4132 String description, String content, String type,
4133 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4134 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4135 boolean andOperator, int start, int end, OrderByComparator obc)
4136 throws SystemException {
4137
4138 QueryDefinition queryDefinition = new QueryDefinition(
4139 status, start, end, obc);
4140
4141 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4142 companyId, groupId, folderIds, classNameId, articleId, version,
4143 title, description, content, type, ddmStructureKeys,
4144 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4145 andOperator, queryDefinition);
4146 }
4147
4148
4195 @Override
4196 public Hits search(
4197 long companyId, long groupId, List<Long> folderIds,
4198 long classNameId, String ddmStructureKey, String ddmTemplateKey,
4199 String keywords, LinkedHashMap<String, Object> params, int start,
4200 int end, Sort sort)
4201 throws SystemException {
4202
4203 String articleId = null;
4204 String title = null;
4205 String description = null;
4206 String content = null;
4207 boolean andOperator = false;
4208
4209 if (Validator.isNotNull(keywords)) {
4210 articleId = keywords;
4211 title = keywords;
4212 description = keywords;
4213 content = keywords;
4214 }
4215 else {
4216 andOperator = true;
4217 }
4218
4219 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
4220
4221 if (params != null) {
4222 params.put("keywords", keywords);
4223 }
4224
4225 return search(
4226 companyId, groupId, folderIds, classNameId, articleId, title,
4227 description, content, null, status, ddmStructureKey, ddmTemplateKey,
4228 params, andOperator, start, end, sort);
4229 }
4230
4231
4292 @Override
4293 public Hits search(
4294 long companyId, long groupId, List<Long> folderIds,
4295 long classNameId, String articleId, String title,
4296 String description, String content, String type, String status,
4297 String ddmStructureKey, String ddmTemplateKey,
4298 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4299 int end, Sort sort)
4300 throws SystemException {
4301
4302 try {
4303 SearchContext searchContext = new SearchContext();
4304
4305 searchContext.setAndSearch(andSearch);
4306
4307 Map<String, Serializable> attributes =
4308 new HashMap<String, Serializable>();
4309
4310 attributes.put(Field.CLASS_NAME_ID, classNameId);
4311 attributes.put(Field.CONTENT, content);
4312 attributes.put(Field.DESCRIPTION, description);
4313 attributes.put(Field.STATUS, status);
4314 attributes.put(Field.TITLE, title);
4315 attributes.put(Field.TYPE, type);
4316 attributes.put("articleId", articleId);
4317 attributes.put("ddmStructureKey", ddmStructureKey);
4318 attributes.put("ddmTemplateKey", ddmTemplateKey);
4319 attributes.put("params", params);
4320
4321 searchContext.setAttributes(attributes);
4322
4323 searchContext.setCompanyId(companyId);
4324 searchContext.setEnd(end);
4325 searchContext.setFolderIds(folderIds);
4326 searchContext.setGroupIds(new long[] {groupId});
4327 searchContext.setIncludeDiscussions(
4328 GetterUtil.getBoolean(params.get("includeDiscussions")));
4329
4330 if (params != null) {
4331 String keywords = (String)params.remove("keywords");
4332
4333 if (Validator.isNotNull(keywords)) {
4334 searchContext.setKeywords(keywords);
4335 }
4336 }
4337
4338 QueryConfig queryConfig = new QueryConfig();
4339
4340 queryConfig.setHighlightEnabled(false);
4341 queryConfig.setScoreEnabled(false);
4342
4343 searchContext.setQueryConfig(queryConfig);
4344
4345 if (sort != null) {
4346 searchContext.setSorts(sort);
4347 }
4348
4349 searchContext.setStart(start);
4350
4351 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4352 JournalArticle.class);
4353
4354 return indexer.search(searchContext);
4355 }
4356 catch (Exception e) {
4357 throw new SystemException(e);
4358 }
4359 }
4360
4361 @Override
4362 public Hits search(
4363 long groupId, long userId, long creatorUserId, int status,
4364 int start, int end)
4365 throws PortalException, SystemException {
4366
4367 Indexer indexer = IndexerRegistryUtil.getIndexer(
4368 JournalArticle.class.getName());
4369
4370 SearchContext searchContext = new SearchContext();
4371
4372 searchContext.setAttribute(Field.STATUS, status);
4373
4374 searchContext.setAttribute("paginationType", "none");
4375
4376 if (creatorUserId > 0) {
4377 searchContext.setAttribute(
4378 Field.USER_ID, String.valueOf(creatorUserId));
4379 }
4380
4381 Group group = groupLocalService.getGroup(groupId);
4382
4383 searchContext.setCompanyId(group.getCompanyId());
4384
4385 searchContext.setEnd(end);
4386 searchContext.setGroupIds(new long[] {groupId});
4387 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4388 searchContext.setStart(start);
4389 searchContext.setUserId(userId);
4390
4391 return indexer.search(searchContext);
4392 }
4393
4394 @Override
4395 public int searchCount(long groupId, List<Long> folderIds, int status)
4396 throws SystemException {
4397
4398 QueryDefinition queryDefinition = new QueryDefinition(status);
4399
4400 return journalArticleFinder.countByG_F(
4401 groupId, folderIds, queryDefinition);
4402 }
4403
4404 @Override
4405 public int searchCount(long groupId, long folderId, int status)
4406 throws SystemException {
4407
4408 List<Long> folderIds = new ArrayList<Long>();
4409
4410 folderIds.add(folderId);
4411
4412 return searchCount(groupId, folderIds, status);
4413 }
4414
4415
4459 @Override
4460 public int searchCount(
4461 long companyId, long groupId, List<Long> folderIds,
4462 long classNameId, String keywords, Double version, String type,
4463 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4464 Date displayDateLT, int status, Date reviewDate)
4465 throws SystemException {
4466
4467 return journalArticleFinder.countByKeywords(
4468 companyId, groupId, folderIds, classNameId, keywords, version, type,
4469 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4470 status, reviewDate);
4471 }
4472
4473
4523 @Override
4524 public int searchCount(
4525 long companyId, long groupId, List<Long> folderIds,
4526 long classNameId, String articleId, Double version, String title,
4527 String description, String content, String type,
4528 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4529 Date displayDateLT, int status, Date reviewDate,
4530 boolean andOperator)
4531 throws SystemException {
4532
4533 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4534 companyId, groupId, folderIds, classNameId, articleId, version,
4535 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4536 displayDateGT, displayDateLT, reviewDate, andOperator,
4537 new QueryDefinition(status));
4538 }
4539
4540
4590 @Override
4591 public int searchCount(
4592 long companyId, long groupId, List<Long> folderIds,
4593 long classNameId, String articleId, Double version, String title,
4594 String description, String content, String type,
4595 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4596 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4597 boolean andOperator)
4598 throws SystemException {
4599
4600 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4601 companyId, groupId, folderIds, classNameId, articleId, version,
4602 title, description, content, type, ddmStructureKeys,
4603 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4604 andOperator, new QueryDefinition(status));
4605 }
4606
4607 @Override
4608 public void setTreePaths(
4609 final long folderId, final String treePath, final boolean reindex)
4610 throws PortalException, SystemException {
4611
4612 if (treePath == null) {
4613 throw new IllegalArgumentException("Tree path is null");
4614 }
4615
4616 final Indexer indexer = IndexerRegistryUtil.getIndexer(
4617 JournalArticle.class.getName());
4618
4619 ActionableDynamicQuery actionableDynamicQuery =
4620 new JournalArticleActionableDynamicQuery() {
4621
4622 @Override
4623 protected void addCriteria(DynamicQuery dynamicQuery) {
4624 Property folderIdProperty = PropertyFactoryUtil.forName(
4625 "folderId");
4626
4627 dynamicQuery.add(folderIdProperty.eq(folderId));
4628
4629 Property treePathProperty = PropertyFactoryUtil.forName(
4630 "treePath");
4631
4632 dynamicQuery.add(
4633 RestrictionsFactoryUtil.or(
4634 treePathProperty.isNull(),
4635 treePathProperty.ne(treePath)));
4636 }
4637
4638 @Override
4639 protected void performAction(Object object)
4640 throws PortalException, SystemException {
4641
4642 JournalArticle article = (JournalArticle)object;
4643
4644 article.setTreePath(treePath);
4645
4646 updateJournalArticle(article);
4647
4648 if (!reindex) {
4649 return;
4650 }
4651
4652 indexer.reindex(article);
4653 }
4654
4655 };
4656
4657 actionableDynamicQuery.performActions();
4658 }
4659
4660
4670 @Override
4671 public void subscribe(long userId, long groupId)
4672 throws PortalException, SystemException {
4673
4674 subscriptionLocalService.addSubscription(
4675 userId, groupId, JournalArticle.class.getName(), groupId);
4676 }
4677
4678
4688 @Override
4689 public void unsubscribe(long userId, long groupId)
4690 throws PortalException, SystemException {
4691
4692 subscriptionLocalService.deleteSubscription(
4693 userId, JournalArticle.class.getName(), groupId);
4694 }
4695
4696
4730 @Override
4731 public JournalArticle updateArticle(
4732 long userId, long groupId, long folderId, String articleId,
4733 double version, Map<Locale, String> titleMap,
4734 Map<Locale, String> descriptionMap, String content,
4735 String layoutUuid, ServiceContext serviceContext)
4736 throws PortalException, SystemException {
4737
4738 User user = userPersistence.findByPrimaryKey(userId);
4739
4740 JournalArticle article = journalArticlePersistence.findByG_A_V(
4741 groupId, articleId, version);
4742
4743 Date displayDate = article.getDisplayDate();
4744
4745 int displayDateMonth = 0;
4746 int displayDateDay = 0;
4747 int displayDateYear = 0;
4748 int displayDateHour = 0;
4749 int displayDateMinute = 0;
4750
4751 if (displayDate != null) {
4752 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4753 user.getTimeZone());
4754
4755 displayCal.setTime(displayDate);
4756
4757 displayDateMonth = displayCal.get(Calendar.MONTH);
4758 displayDateDay = displayCal.get(Calendar.DATE);
4759 displayDateYear = displayCal.get(Calendar.YEAR);
4760 displayDateHour = displayCal.get(Calendar.HOUR);
4761 displayDateMinute = displayCal.get(Calendar.MINUTE);
4762
4763 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4764 displayDateHour += 12;
4765 }
4766 }
4767
4768 Date expirationDate = article.getExpirationDate();
4769
4770 int expirationDateMonth = 0;
4771 int expirationDateDay = 0;
4772 int expirationDateYear = 0;
4773 int expirationDateHour = 0;
4774 int expirationDateMinute = 0;
4775 boolean neverExpire = true;
4776
4777 if (expirationDate != null) {
4778 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4779 user.getTimeZone());
4780
4781 expirationCal.setTime(expirationDate);
4782
4783 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4784 expirationDateDay = expirationCal.get(Calendar.DATE);
4785 expirationDateYear = expirationCal.get(Calendar.YEAR);
4786 expirationDateHour = expirationCal.get(Calendar.HOUR);
4787 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4788 neverExpire = false;
4789
4790 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4791 expirationDateHour += 12;
4792 }
4793 }
4794
4795 Date reviewDate = article.getReviewDate();
4796
4797 int reviewDateMonth = 0;
4798 int reviewDateDay = 0;
4799 int reviewDateYear = 0;
4800 int reviewDateHour = 0;
4801 int reviewDateMinute = 0;
4802 boolean neverReview = true;
4803
4804 if (reviewDate != null) {
4805 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4806 user.getTimeZone());
4807
4808 reviewCal.setTime(reviewDate);
4809
4810 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4811 reviewDateDay = reviewCal.get(Calendar.DATE);
4812 reviewDateYear = reviewCal.get(Calendar.YEAR);
4813 reviewDateHour = reviewCal.get(Calendar.HOUR);
4814 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4815 neverReview = false;
4816
4817 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4818 reviewDateHour += 12;
4819 }
4820 }
4821
4822 return journalArticleLocalService.updateArticle(
4823 userId, groupId, folderId, articleId, version, titleMap,
4824 descriptionMap, content, article.getType(),
4825 article.getStructureId(), article.getTemplateId(), layoutUuid,
4826 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4827 displayDateMinute, expirationDateMonth, expirationDateDay,
4828 expirationDateYear, expirationDateHour, expirationDateMinute,
4829 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4830 reviewDateHour, reviewDateMinute, neverReview,
4831 article.getIndexable(), article.isSmallImage(),
4832 article.getSmallImageURL(), null, null, null, serviceContext);
4833 }
4834
4835
4922 @Indexable(type = IndexableType.REINDEX)
4923 @Override
4924 public JournalArticle updateArticle(
4925 long userId, long groupId, long folderId, String articleId,
4926 double version, Map<Locale, String> titleMap,
4927 Map<Locale, String> descriptionMap, String content, String type,
4928 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4929 int displayDateMonth, int displayDateDay, int displayDateYear,
4930 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4931 int expirationDateDay, int expirationDateYear,
4932 int expirationDateHour, int expirationDateMinute,
4933 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4934 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4935 boolean neverReview, boolean indexable, boolean smallImage,
4936 String smallImageURL, File smallImageFile,
4937 Map<String, byte[]> images, String articleURL,
4938 ServiceContext serviceContext)
4939 throws PortalException, SystemException {
4940
4941
4942
4943 User user = userPersistence.findByPrimaryKey(userId);
4944 articleId = StringUtil.toUpperCase(articleId.trim());
4945
4946 byte[] smallImageBytes = null;
4947
4948 try {
4949 smallImageBytes = FileUtil.getBytes(smallImageFile);
4950 }
4951 catch (IOException ioe) {
4952 }
4953
4954 JournalArticle latestArticle = getLatestArticle(
4955 groupId, articleId, WorkflowConstants.STATUS_ANY);
4956
4957 JournalArticle article = latestArticle;
4958
4959 boolean imported = ExportImportThreadLocal.isImportInProcess();
4960
4961 double latestVersion = latestArticle.getVersion();
4962
4963 boolean addNewVersion = false;
4964
4965 if (imported) {
4966 if (latestVersion > version) {
4967 JournalArticle existingArticle =
4968 journalArticlePersistence.fetchByG_A_V(
4969 groupId, articleId, version);
4970
4971 if (existingArticle != null) {
4972 article = existingArticle;
4973 }
4974 else {
4975 addNewVersion = true;
4976 }
4977 }
4978 else if (latestVersion < version) {
4979 addNewVersion = true;
4980 }
4981 }
4982 else {
4983 if ((version > 0) && (version != latestVersion)) {
4984 throw new ArticleVersionException();
4985 }
4986
4987 serviceContext.validateModifiedDate(
4988 latestArticle, ArticleVersionException.class);
4989
4990 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4991 latestArticle.isScheduled()) {
4992
4993 addNewVersion = true;
4994
4995 version = getNextVersion(article);
4996 }
4997 }
4998
4999 Date displayDate = null;
5000 Date expirationDate = null;
5001 Date reviewDate = null;
5002
5003 if (article.getClassNameId() ==
5004 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5005
5006 displayDate = PortalUtil.getDate(
5007 displayDateMonth, displayDateDay, displayDateYear,
5008 displayDateHour, displayDateMinute, user.getTimeZone(),
5009 ArticleDisplayDateException.class);
5010
5011 if (!neverExpire) {
5012 expirationDate = PortalUtil.getDate(
5013 expirationDateMonth, expirationDateDay, expirationDateYear,
5014 expirationDateHour, expirationDateMinute,
5015 user.getTimeZone(), ArticleExpirationDateException.class);
5016 }
5017
5018 if (!neverReview) {
5019 reviewDate = PortalUtil.getDate(
5020 reviewDateMonth, reviewDateDay, reviewDateYear,
5021 reviewDateHour, reviewDateMinute, user.getTimeZone(),
5022 ArticleReviewDateException.class);
5023 }
5024 }
5025
5026 Date now = new Date();
5027
5028 boolean expired = false;
5029
5030 if ((expirationDate != null) && expirationDate.before(now)) {
5031 expired = true;
5032 }
5033
5034 validate(
5035 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
5036 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
5037 displayDate, expirationDate, smallImage, smallImageURL,
5038 smallImageFile, smallImageBytes, serviceContext);
5039
5040 if (addNewVersion) {
5041 long id = counterLocalService.increment();
5042
5043 article = journalArticlePersistence.create(id);
5044
5045 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
5046 article.setGroupId(latestArticle.getGroupId());
5047 article.setCompanyId(latestArticle.getCompanyId());
5048 article.setUserId(user.getUserId());
5049 article.setUserName(user.getFullName());
5050 article.setCreateDate(latestArticle.getCreateDate());
5051 article.setClassNameId(latestArticle.getClassNameId());
5052 article.setClassPK(latestArticle.getClassPK());
5053 article.setArticleId(articleId);
5054 article.setVersion(version);
5055 article.setSmallImageId(latestArticle.getSmallImageId());
5056 }
5057
5058 Locale locale = getArticleDefaultLocale(content, serviceContext);
5059
5060 String title = titleMap.get(locale);
5061
5062 content = format(
5063 user, groupId, articleId, article.getVersion(), addNewVersion,
5064 content, ddmStructureKey, images);
5065
5066 article.setModifiedDate(serviceContext.getModifiedDate(now));
5067 article.setFolderId(folderId);
5068 article.setTreePath(article.buildTreePath());
5069 article.setTitleMap(titleMap, locale);
5070 article.setUrlTitle(
5071 getUniqueUrlTitle(
5072 article.getId(), article.getArticleId(), title,
5073 latestArticle.getUrlTitle(), serviceContext));
5074 article.setDescriptionMap(descriptionMap, locale);
5075 article.setContent(content);
5076 article.setType(type);
5077 article.setStructureId(ddmStructureKey);
5078 article.setTemplateId(ddmTemplateKey);
5079 article.setLayoutUuid(layoutUuid);
5080 article.setDisplayDate(displayDate);
5081 article.setExpirationDate(expirationDate);
5082 article.setReviewDate(reviewDate);
5083 article.setIndexable(indexable);
5084 article.setSmallImage(smallImage);
5085
5086 if (smallImage) {
5087 if ((smallImageFile != null) && (smallImageBytes != null)) {
5088 article.setSmallImageId(counterLocalService.increment());
5089 }
5090 }
5091 else {
5092 article.setSmallImageId(0);
5093 }
5094
5095 article.setSmallImageURL(smallImageURL);
5096
5097 if (latestArticle.isPending()) {
5098 article.setStatus(latestArticle.getStatus());
5099 }
5100 else if (!expired) {
5101 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5102 }
5103 else {
5104 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5105 }
5106
5107 ExpandoBridgeUtil.setExpandoBridgeAttributes(
5108 latestArticle.getExpandoBridge(), article.getExpandoBridge(),
5109 serviceContext);
5110
5111 journalArticlePersistence.update(article);
5112
5113
5114
5115 if (hasModifiedLatestApprovedVersion(groupId, articleId, version)) {
5116 updateAsset(
5117 userId, article, serviceContext.getAssetCategoryIds(),
5118 serviceContext.getAssetTagNames(),
5119 serviceContext.getAssetLinkEntryIds());
5120 }
5121
5122
5123
5124 if (PortalUtil.getClassNameId(DDMStructure.class) ==
5125 article.getClassNameId()) {
5126
5127 updateDDMStructureXSD(
5128 article.getClassPK(), content, serviceContext);
5129 }
5130
5131
5132
5133 saveImages(
5134 smallImage, article.getSmallImageId(), smallImageFile,
5135 smallImageBytes);
5136
5137
5138
5139 PortletPreferences preferences =
5140 ServiceContextUtil.getPortletPreferences(serviceContext);
5141
5142
5143
5144 if (expired && imported) {
5145 updateStatus(
5146 userId, article, article.getStatus(), articleURL,
5147 new HashMap<String, Serializable>(), serviceContext);
5148 }
5149
5150 if (serviceContext.getWorkflowAction() ==
5151 WorkflowConstants.ACTION_PUBLISH) {
5152
5153 articleURL = buildArticleURL(
5154 articleURL, groupId, folderId, articleId);
5155
5156 serviceContext.setAttribute("articleURL", articleURL);
5157
5158 sendEmail(
5159 article, articleURL, preferences, "requested", serviceContext);
5160
5161 WorkflowHandlerRegistryUtil.startWorkflowInstance(
5162 user.getCompanyId(), groupId, userId,
5163 JournalArticle.class.getName(), article.getId(), article,
5164 serviceContext);
5165 }
5166
5167 return journalArticlePersistence.findByPrimaryKey(article.getId());
5168 }
5169
5170
5199 @Override
5200 public JournalArticle updateArticle(
5201 long userId, long groupId, long folderId, String articleId,
5202 double version, String content, ServiceContext serviceContext)
5203 throws PortalException, SystemException {
5204
5205 JournalArticle article = journalArticlePersistence.findByG_A_V(
5206 groupId, articleId, version);
5207
5208 return journalArticleLocalService.updateArticle(
5209 userId, groupId, folderId, articleId, version,
5210 article.getTitleMap(), article.getDescriptionMap(), content,
5211 article.getLayoutUuid(), serviceContext);
5212 }
5213
5214
5219 @Override
5220 public JournalArticle updateArticleTranslation(
5221 long groupId, String articleId, double version, Locale locale,
5222 String title, String description, String content,
5223 Map<String, byte[]> images)
5224 throws PortalException, SystemException {
5225
5226 return journalArticleLocalService.updateArticleTranslation(
5227 groupId, articleId, version, locale, title, description, content,
5228 images, null);
5229 }
5230
5231
5253 @Indexable(type = IndexableType.REINDEX)
5254 @Override
5255 public JournalArticle updateArticleTranslation(
5256 long groupId, String articleId, double version, Locale locale,
5257 String title, String description, String content,
5258 Map<String, byte[]> images, ServiceContext serviceContext)
5259 throws PortalException, SystemException {
5260
5261 validateContent(content);
5262
5263 JournalArticle oldArticle = getLatestArticle(
5264 groupId, articleId, WorkflowConstants.STATUS_ANY);
5265
5266 double oldVersion = oldArticle.getVersion();
5267
5268 if ((version > 0) && (version != oldVersion)) {
5269 throw new ArticleVersionException();
5270 }
5271
5272 boolean incrementVersion = false;
5273
5274 if (oldArticle.isApproved() || oldArticle.isExpired()) {
5275 incrementVersion = true;
5276 }
5277
5278 if (serviceContext != null) {
5279 serviceContext.validateModifiedDate(
5280 oldArticle, ArticleVersionException.class);
5281 }
5282
5283 JournalArticle article = null;
5284
5285 User user = userPersistence.fetchByPrimaryKey(
5286 serviceContext.getUserId());
5287
5288 if (user == null) {
5289 user = userPersistence.fetchByC_U(
5290 oldArticle.getCompanyId(), oldArticle.getUserId());
5291
5292 if (user == null) {
5293 user = userPersistence.fetchByC_DU(
5294 oldArticle.getCompanyId(), true);
5295 }
5296 }
5297
5298 Locale defaultLocale = getArticleDefaultLocale(content, serviceContext);
5299
5300 if (incrementVersion) {
5301 double newVersion = getNextVersion(oldArticle);
5302
5303 long id = counterLocalService.increment();
5304
5305 article = journalArticlePersistence.create(id);
5306
5307 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
5308 article.setGroupId(oldArticle.getGroupId());
5309 article.setCompanyId(oldArticle.getCompanyId());
5310 article.setUserId(user.getUserId());
5311 article.setUserName(user.getFullName());
5312 article.setCreateDate(new Date());
5313 article.setModifiedDate(new Date());
5314 article.setFolderId(oldArticle.getFolderId());
5315 article.setClassNameId(oldArticle.getClassNameId());
5316 article.setClassPK(oldArticle.getClassPK());
5317 article.setArticleId(articleId);
5318 article.setVersion(newVersion);
5319 article.setTitleMap(oldArticle.getTitleMap(), defaultLocale);
5320 article.setUrlTitle(
5321 getUniqueUrlTitle(
5322 id, articleId, title, oldArticle.getUrlTitle(),
5323 serviceContext));
5324 article.setDescriptionMap(oldArticle.getDescriptionMap());
5325 article.setType(oldArticle.getType());
5326 article.setStructureId(oldArticle.getStructureId());
5327 article.setTemplateId(oldArticle.getTemplateId());
5328 article.setLayoutUuid(oldArticle.getLayoutUuid());
5329 article.setDisplayDate(oldArticle.getDisplayDate());
5330 article.setExpirationDate(oldArticle.getExpirationDate());
5331 article.setReviewDate(oldArticle.getReviewDate());
5332 article.setIndexable(oldArticle.getIndexable());
5333 article.setSmallImage(oldArticle.getSmallImage());
5334 article.setSmallImageId(oldArticle.getSmallImageId());
5335
5336 if (article.getSmallImageId() == 0) {
5337 article.setSmallImageId(counterLocalService.increment());
5338 }
5339
5340 article.setSmallImageURL(oldArticle.getSmallImageURL());
5341
5342 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5343 article.setStatusDate(new Date());
5344
5345 ExpandoBridgeUtil.copyExpandoBridgeAttributes(
5346 oldArticle.getExpandoBridge(), article.getExpandoBridge());
5347 }
5348 else {
5349 article = oldArticle;
5350 }
5351
5352 Map<Locale, String> titleMap = article.getTitleMap();
5353
5354 titleMap.put(locale, title);
5355
5356 article.setTitleMap(titleMap, defaultLocale);
5357
5358 Map<Locale, String> descriptionMap = article.getDescriptionMap();
5359
5360 descriptionMap.put(locale, description);
5361
5362 article.setDescriptionMap(descriptionMap);
5363
5364 content = format(
5365 user, groupId, articleId, article.getVersion(),
5366 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
5367 images);
5368
5369 article.setContent(content);
5370
5371 journalArticlePersistence.update(article);
5372
5373 return article;
5374 }
5375
5376
5389 @Override
5390 public void updateAsset(
5391 long userId, JournalArticle article, long[] assetCategoryIds,
5392 String[] assetTagNames, long[] assetLinkEntryIds)
5393 throws PortalException, SystemException {
5394
5395 boolean visible = article.isApproved();
5396
5397 if (article.getClassNameId() !=
5398 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5399
5400 visible = false;
5401 }
5402
5403 boolean addDraftAssetEntry = false;
5404
5405 if (!article.isApproved() &&
5406 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5407
5408 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5409 article.getGroupId(), article.getArticleId(),
5410 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5411
5412 if (approvedArticlesCount > 0) {
5413 addDraftAssetEntry = true;
5414 }
5415 }
5416
5417 AssetEntry assetEntry = null;
5418
5419 if (addDraftAssetEntry) {
5420 assetEntry = assetEntryLocalService.updateEntry(
5421 userId, article.getGroupId(), article.getCreateDate(),
5422 article.getModifiedDate(), JournalArticle.class.getName(),
5423 article.getPrimaryKey(), article.getUuid(),
5424 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5425 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5426 article.getDescription(), article.getDescription(), null,
5427 article.getLayoutUuid(), 0, 0, null, false);
5428 }
5429 else {
5430 JournalArticleResource journalArticleResource =
5431 journalArticleResourceLocalService.getArticleResource(
5432 article.getResourcePrimKey());
5433
5434 Date publishDate = null;
5435
5436 if (article.isApproved()) {
5437 publishDate = article.getDisplayDate();
5438 }
5439
5440 assetEntry = assetEntryLocalService.updateEntry(
5441 userId, article.getGroupId(), article.getCreateDate(),
5442 article.getModifiedDate(), JournalArticle.class.getName(),
5443 journalArticleResource.getResourcePrimKey(),
5444 journalArticleResource.getUuid(), getClassTypeId(article),
5445 assetCategoryIds, assetTagNames, visible, null, null, null,
5446 publishDate, ContentTypes.TEXT_HTML, article.getTitle(),
5447 article.getDescription(), article.getDescription(), null,
5448 article.getLayoutUuid(), 0, 0, null, false);
5449 }
5450
5451 assetLinkLocalService.updateLinks(
5452 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5453 AssetLinkConstants.TYPE_RELATED);
5454 }
5455
5456
5471 @Indexable(type = IndexableType.REINDEX)
5472 @Override
5473 public JournalArticle updateContent(
5474 long groupId, String articleId, double version, String content)
5475 throws PortalException, SystemException {
5476
5477 JournalArticle article = journalArticlePersistence.findByG_A_V(
5478 groupId, articleId, version);
5479
5480 article.setContent(content);
5481
5482 journalArticlePersistence.update(article);
5483
5484 return article;
5485 }
5486
5487
5510 @Indexable(type = IndexableType.REINDEX)
5511 @Override
5512 public JournalArticle updateStatus(
5513 long userId, JournalArticle article, int status, String articleURL,
5514 Map<String, Serializable> workflowContext,
5515 ServiceContext serviceContext)
5516 throws PortalException, SystemException {
5517
5518
5519
5520 User user = userPersistence.findByPrimaryKey(userId);
5521 Date now = new Date();
5522
5523 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5524 (article.getClassNameId() ==
5525 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5526 (article.getDisplayDate() != null) &&
5527 now.before(article.getDisplayDate())) {
5528
5529 status = WorkflowConstants.STATUS_SCHEDULED;
5530 }
5531
5532 int oldStatus = article.getStatus();
5533
5534 if (status == WorkflowConstants.STATUS_APPROVED) {
5535 Date expirationDate = article.getExpirationDate();
5536
5537 if ((expirationDate != null) && expirationDate.before(now)) {
5538 article.setExpirationDate(null);
5539 }
5540 }
5541
5542 if (status == WorkflowConstants.STATUS_EXPIRED) {
5543 article.setExpirationDate(now);
5544 }
5545
5546 article.setStatus(status);
5547 article.setStatusByUserId(user.getUserId());
5548 article.setStatusByUserName(user.getFullName());
5549 article.setStatusDate(serviceContext.getModifiedDate(now));
5550
5551 journalArticlePersistence.update(article);
5552
5553 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5554 setArticlesExpirationDate(article);
5555 }
5556
5557 if (hasModifiedLatestApprovedVersion(
5558 article.getGroupId(), article.getArticleId(),
5559 article.getVersion())) {
5560
5561 if (status == WorkflowConstants.STATUS_APPROVED) {
5562 updateUrlTitles(
5563 article.getGroupId(), article.getArticleId(),
5564 article.getUrlTitle());
5565
5566
5567
5568 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5569 (article.getVersion() !=
5570 JournalArticleConstants.VERSION_DEFAULT)) {
5571
5572 AssetEntry draftAssetEntry =
5573 assetEntryLocalService.fetchEntry(
5574 JournalArticle.class.getName(),
5575 article.getPrimaryKey());
5576
5577 if (draftAssetEntry != null) {
5578 long[] assetCategoryIds =
5579 draftAssetEntry.getCategoryIds();
5580 String[] assetTagNames = draftAssetEntry.getTagNames();
5581
5582 List<AssetLink> assetLinks =
5583 assetLinkLocalService.getDirectLinks(
5584 draftAssetEntry.getEntryId(),
5585 AssetLinkConstants.TYPE_RELATED, false);
5586
5587 long[] assetLinkEntryIds = StringUtil.split(
5588 ListUtil.toString(
5589 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5590
5591 AssetEntry assetEntry =
5592 assetEntryLocalService.updateEntry(
5593 userId, article.getGroupId(),
5594 article.getCreateDate(),
5595 article.getModifiedDate(),
5596 JournalArticle.class.getName(),
5597 article.getResourcePrimKey(), article.getUuid(),
5598 getClassTypeId(article), assetCategoryIds,
5599 assetTagNames, false, null, null, null,
5600 ContentTypes.TEXT_HTML, article.getTitle(),
5601 article.getDescription(),
5602 article.getDescription(), null,
5603 article.getLayoutUuid(), 0, 0, null, false);
5604
5605 assetLinkLocalService.updateLinks(
5606 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5607 AssetLinkConstants.TYPE_RELATED);
5608
5609 SystemEventHierarchyEntryThreadLocal.push(
5610 JournalArticle.class);
5611
5612 try {
5613 assetEntryLocalService.deleteEntry(
5614 JournalArticle.class.getName(),
5615 article.getPrimaryKey());
5616 }
5617 finally {
5618 SystemEventHierarchyEntryThreadLocal.pop(
5619 JournalArticle.class);
5620 }
5621 }
5622 }
5623
5624 if (article.getClassNameId() ==
5625 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5626
5627 assetEntryLocalService.updateEntry(
5628 JournalArticle.class.getName(),
5629 article.getResourcePrimKey(), article.getDisplayDate(),
5630 article.getExpirationDate(), true);
5631 }
5632
5633
5634
5635 JSONObject extraDataJSONObject =
5636 JSONFactoryUtil.createJSONObject();
5637
5638 extraDataJSONObject.put("title", article.getTitle());
5639
5640 if (serviceContext.isCommandUpdate()) {
5641 socialActivityLocalService.addActivity(
5642 user.getUserId(), article.getGroupId(),
5643 JournalArticle.class.getName(),
5644 article.getResourcePrimKey(),
5645 JournalActivityKeys.UPDATE_ARTICLE,
5646 extraDataJSONObject.toString(), 0);
5647 }
5648 else {
5649 socialActivityLocalService.addUniqueActivity(
5650 user.getUserId(), article.getGroupId(),
5651 JournalArticle.class.getName(),
5652 article.getResourcePrimKey(),
5653 JournalActivityKeys.ADD_ARTICLE,
5654 extraDataJSONObject.toString(), 0);
5655 }
5656 }
5657 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5658 updatePreviousApprovedArticle(article);
5659 }
5660 }
5661
5662 if ((article.getClassNameId() ==
5663 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5664 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5665 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5666
5667
5668
5669 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5670 ((status == WorkflowConstants.STATUS_APPROVED) ||
5671 (status == WorkflowConstants.STATUS_DENIED))) {
5672
5673 String msg = "granted";
5674
5675 if (status == WorkflowConstants.STATUS_DENIED) {
5676 msg = "denied";
5677 }
5678
5679 try {
5680 PortletPreferences preferences =
5681 ServiceContextUtil.getPortletPreferences(
5682 serviceContext);
5683
5684 articleURL = buildArticleURL(
5685 articleURL, article.getGroupId(), article.getFolderId(),
5686 article.getArticleId());
5687
5688 sendEmail(
5689 article, articleURL, preferences, msg, serviceContext);
5690 }
5691 catch (Exception e) {
5692 _log.error(
5693 "Unable to send email to notify the change of status " +
5694 " to " + msg + " for article " + article.getId() +
5695 ": " + e.getMessage());
5696 }
5697 }
5698
5699
5700
5701 notifySubscribers(article, serviceContext);
5702 }
5703
5704 return article;
5705 }
5706
5707 protected void setArticlesExpirationDate(JournalArticle article)
5708 throws SystemException {
5709
5710 if (ExportImportThreadLocal.isImportInProcess()) {
5711 return;
5712 }
5713
5714 if (!article.isApproved() || (article.getExpirationDate() == null)) {
5715 return;
5716 }
5717
5718 final List<JournalArticle> articles =
5719 journalArticlePersistence.findByG_A(
5720 article.getGroupId(), article.getArticleId());
5721
5722 final Date expirationDate = article.getExpirationDate();
5723
5724 TransactionCommitCallbackRegistryUtil.registerCallback(
5725 new Callable<Void>() {
5726
5727 @Override
5728 public Void call() throws Exception {
5729 for (JournalArticle curArticle : articles) {
5730 curArticle.setExpirationDate(expirationDate);
5731
5732 journalArticleLocalService.updateJournalArticle(
5733 curArticle);
5734 }
5735
5736 return null;
5737 }
5738
5739 });
5740 }
5741
5742
5763 @Override
5764 public JournalArticle updateStatus(
5765 long userId, long classPK, int status,
5766 Map<String, Serializable> workflowContext,
5767 ServiceContext serviceContext)
5768 throws PortalException, SystemException {
5769
5770 JournalArticle article = getArticle(classPK);
5771
5772 return journalArticleLocalService.updateStatus(
5773 userId, article, status, null, workflowContext, serviceContext);
5774 }
5775
5776
5798 @Override
5799 public JournalArticle updateStatus(
5800 long userId, long groupId, String articleId, double version,
5801 int status, String articleURL,
5802 Map<String, Serializable> workflowContext,
5803 ServiceContext serviceContext)
5804 throws PortalException, SystemException {
5805
5806 JournalArticle article = journalArticlePersistence.findByG_A_V(
5807 groupId, articleId, version);
5808
5809 return journalArticleLocalService.updateStatus(
5810 userId, article, status, articleURL, workflowContext,
5811 serviceContext);
5812 }
5813
5814
5829 @Override
5830 public void updateTemplateId(
5831 long groupId, long classNameId, String oldDDMTemplateKey,
5832 String newDDMTemplateKey)
5833 throws SystemException {
5834
5835 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5836 groupId, classNameId, oldDDMTemplateKey);
5837
5838 for (JournalArticle article : articles) {
5839 article.setTemplateId(newDDMTemplateKey);
5840
5841 journalArticlePersistence.update(article);
5842 }
5843 }
5844
5845 protected String buildArticleURL(
5846 String articleURL, long groupId, long folderId, String articleId) {
5847
5848 StringBundler sb = new StringBundler(13);
5849
5850 sb.append(articleURL);
5851 sb.append(StringPool.AMPERSAND);
5852 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5853 sb.append("groupId=");
5854 sb.append(groupId);
5855 sb.append(StringPool.AMPERSAND);
5856 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5857 sb.append("folderId=");
5858 sb.append(folderId);
5859 sb.append(StringPool.AMPERSAND);
5860 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5861 sb.append("articleId=");
5862 sb.append(articleId);
5863
5864 return sb.toString();
5865 }
5866
5867 protected void checkArticlesByDisplayDate(Date displayDate)
5868 throws PortalException, SystemException {
5869
5870 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5871 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5872
5873 for (JournalArticle article : articles) {
5874 ServiceContext serviceContext = new ServiceContext();
5875
5876 serviceContext.setCommand(Constants.UPDATE);
5877
5878 String layoutFullURL = PortalUtil.getLayoutFullURL(
5879 article.getGroupId(), PortletKeys.JOURNAL);
5880
5881 serviceContext.setLayoutFullURL(layoutFullURL);
5882
5883 serviceContext.setScopeGroupId(article.getGroupId());
5884
5885 journalArticleLocalService.updateStatus(
5886 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5887 null, new HashMap<String, Serializable>(), serviceContext);
5888 }
5889 }
5890
5891 protected void checkArticlesByExpirationDate(Date expirationDate)
5892 throws PortalException, SystemException {
5893
5894 List<JournalArticle> articles =
5895 journalArticleFinder.findByExpirationDate(
5896 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5897 new Date(
5898 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5899 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5900
5901 if (_log.isDebugEnabled()) {
5902 _log.debug("Expiring " + articles.size() + " articles");
5903 }
5904
5905 Set<Long> companyIds = new HashSet<Long>();
5906
5907 for (JournalArticle article : articles) {
5908 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5909 List<JournalArticle> currentArticles =
5910 journalArticlePersistence.findByG_A(
5911 article.getGroupId(), article.getArticleId(),
5912 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5913 new ArticleVersionComparator(true));
5914
5915 for (JournalArticle currentArticle : currentArticles) {
5916 if ((currentArticle.getExpirationDate() == null) ||
5917 (currentArticle.getVersion() > article.getVersion())) {
5918
5919 continue;
5920 }
5921
5922 currentArticle.setExpirationDate(
5923 article.getExpirationDate());
5924 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5925
5926 journalArticlePersistence.update(currentArticle);
5927 }
5928 }
5929 else {
5930 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5931
5932 journalArticlePersistence.update(article);
5933 }
5934
5935 updatePreviousApprovedArticle(article);
5936
5937 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5938 JournalArticle.class);
5939
5940 indexer.reindex(article);
5941
5942 JournalContentUtil.clearCache(
5943 article.getGroupId(), article.getArticleId(),
5944 article.getTemplateId());
5945
5946 companyIds.add(article.getCompanyId());
5947 }
5948
5949 for (long companyId : companyIds) {
5950 CacheUtil.clearCache(companyId);
5951 }
5952
5953 if (_previousCheckDate == null) {
5954 _previousCheckDate = new Date(
5955 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5956 }
5957 }
5958
5959 protected void checkArticlesByReviewDate(Date reviewDate)
5960 throws PortalException, SystemException {
5961
5962 List<JournalArticle> latestArticles = new ArrayList<JournalArticle>();
5963
5964 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5965 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5966 _previousCheckDate);
5967
5968 for (JournalArticle article : articles) {
5969 long groupId = article.getGroupId();
5970 String articleId = article.getArticleId();
5971 double version = article.getVersion();
5972
5973 if (!journalArticleLocalService.isLatestVersion(
5974 groupId, articleId, version)) {
5975
5976 article = journalArticleLocalService.getLatestArticle(
5977 groupId, articleId);
5978 }
5979
5980 if (!latestArticles.contains(article)) {
5981 if (_log.isDebugEnabled()) {
5982 _log.debug(
5983 "Sending review notification for article " +
5984 article.getId());
5985 }
5986
5987 latestArticles.add(article);
5988
5989 String articleURL = StringPool.BLANK;
5990
5991 long ownerId = article.getGroupId();
5992 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5993 long plid = PortletKeys.PREFS_PLID_SHARED;
5994 String portletId = PortletKeys.JOURNAL;
5995
5996 PortletPreferences preferences =
5997 portletPreferencesLocalService.getPreferences(
5998 article.getCompanyId(), ownerId, ownerType, plid,
5999 portletId);
6000
6001 sendEmail(
6002 article, articleURL, preferences, "review",
6003 new ServiceContext());
6004 }
6005 }
6006 }
6007
6008 protected void checkStructure(Document contentDoc, Element root)
6009 throws PortalException {
6010
6011 for (Element el : root.elements()) {
6012 checkStructureField(el, contentDoc);
6013
6014 checkStructure(contentDoc, el);
6015 }
6016 }
6017
6018 protected void checkStructure(JournalArticle article)
6019 throws PortalException, SystemException {
6020
6021 Group companyGroup = groupLocalService.getCompanyGroup(
6022 article.getCompanyId());
6023
6024 DDMStructure structure = null;
6025
6026 try {
6027 structure = ddmStructurePersistence.findByG_C_S(
6028 PortalUtil.getSiteGroupId(article.getGroupId()),
6029 PortalUtil.getClassNameId(JournalArticle.class),
6030 article.getStructureId());
6031 }
6032 catch (NoSuchStructureException nsse) {
6033 structure = ddmStructurePersistence.findByG_C_S(
6034 companyGroup.getGroupId(),
6035 PortalUtil.getClassNameId(JournalArticle.class),
6036 article.getStructureId());
6037 }
6038
6039 String content = GetterUtil.getString(article.getContent());
6040
6041 try {
6042 Document contentDocument = SAXReaderUtil.read(content);
6043 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
6044
6045 checkStructure(contentDocument, xsdDocument.getRootElement());
6046 }
6047 catch (DocumentException de) {
6048 throw new SystemException(de);
6049 }
6050 catch (StructureXsdException sxsde) {
6051 long groupId = article.getGroupId();
6052 String articleId = article.getArticleId();
6053 double version = article.getVersion();
6054
6055 if (_log.isWarnEnabled()) {
6056 _log.warn(
6057 "Article {groupId=" + groupId + ", articleId=" +
6058 articleId + ", version=" + version +
6059 "} has content that does not match its " +
6060 "structure: " + sxsde.getMessage());
6061 }
6062 }
6063 }
6064
6065 protected void checkStructureField(Element el, Document contentDoc)
6066 throws PortalException {
6067
6068 StringBuilder elPath = new StringBuilder();
6069
6070 elPath.append(el.attributeValue("name"));
6071
6072 Element elParent = el.getParent();
6073
6074 while (true) {
6075 if ((elParent == null) || elParent.getName().equals("root")) {
6076 break;
6077 }
6078
6079 elPath.insert(
6080 0, elParent.attributeValue("name") + StringPool.COMMA);
6081
6082 elParent = elParent.getParent();
6083 }
6084
6085 String[] elPathNames = StringUtil.split(elPath.toString());
6086
6087 Element contentEl = contentDoc.getRootElement();
6088
6089 for (String _elPathName : elPathNames) {
6090 boolean foundEl = false;
6091
6092 for (Element tempEl : contentEl.elements()) {
6093 if (_elPathName.equals(
6094 tempEl.attributeValue("name", StringPool.BLANK))) {
6095
6096 contentEl = tempEl;
6097 foundEl = true;
6098
6099 break;
6100 }
6101 }
6102
6103 if (!foundEl) {
6104 String elType = contentEl.attributeValue(
6105 "type", StringPool.BLANK);
6106
6107 if (!elType.equals("list") && !elType.equals("multi-list")) {
6108 throw new StructureXsdException(elPath.toString());
6109 }
6110
6111 break;
6112 }
6113 }
6114 }
6115
6116 protected void copyArticleImages(
6117 JournalArticle oldArticle, JournalArticle newArticle)
6118 throws Exception {
6119
6120 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
6121
6122 XPath xPathSelector = SAXReaderUtil.createXPath(
6123 "
6124
6125 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
6126
6127 for (Node imageNode : imageNodes) {
6128 Element imageEl = (Element)imageNode;
6129
6130 String elInstanceId = imageEl.attributeValue("instance-id");
6131 String elName = imageEl.attributeValue("name");
6132 String elIndex = imageEl.attributeValue("index");
6133
6134 String name = elName + StringPool.UNDERLINE + elIndex;
6135
6136 List<Element> dynamicContentEls = imageEl.elements(
6137 "dynamic-content");
6138
6139 for (Element dynamicContentEl : dynamicContentEls) {
6140 long imageId = GetterUtil.getLong(
6141 dynamicContentEl.attributeValue("id"));
6142 String languageId =
6143 StringPool.UNDERLINE +
6144 dynamicContentEl.attributeValue("language-id");
6145
6146 Image oldImage = imageLocalService.fetchImage(imageId);
6147
6148 if (oldImage == null) {
6149 continue;
6150 }
6151
6152 imageId = journalArticleImageLocalService.getArticleImageId(
6153 newArticle.getGroupId(), newArticle.getArticleId(),
6154 newArticle.getVersion(), elInstanceId, name, languageId);
6155
6156 imageLocalService.updateImage(imageId, oldImage.getTextObj());
6157
6158 String elContent =
6159 "/image/journal/article?img_id=" + imageId + "&t=" +
6160 WebServerServletTokenUtil.getToken(imageId);
6161
6162 dynamicContentEl.setText(elContent);
6163 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
6164 }
6165 }
6166
6167 newArticle.setContent(contentDoc.formattedString());
6168 }
6169
6170 protected JournalArticle fetchLatestLiveArticle(JournalArticle article)
6171 throws PortalException, SystemException {
6172
6173 Group group = groupLocalService.getGroup(article.getGroupId());
6174
6175 long liveGroupId = group.getLiveGroupId();
6176
6177 if (liveGroupId == 0) {
6178 return null;
6179 }
6180
6181 JournalArticleResource articleResource =
6182 journalArticleResourceLocalService.
6183 fetchJournalArticleResourceByUuidAndGroupId(
6184 article.getArticleResourceUuid(), liveGroupId);
6185
6186 if (articleResource == null) {
6187 return null;
6188 }
6189
6190 return journalArticleLocalService.fetchLatestArticle(
6191 articleResource.getResourcePrimKey(), WorkflowConstants.STATUS_ANY,
6192 false);
6193 }
6194
6195 protected void format(
6196 User user, long groupId, String articleId, double version,
6197 boolean incrementVersion, Element root, Map<String, byte[]> images)
6198 throws PortalException, SystemException {
6199
6200 for (Element element : root.elements()) {
6201 String elInstanceId = element.attributeValue(
6202 "instance-id", StringPool.BLANK);
6203 String elType = element.attributeValue("type", StringPool.BLANK);
6204
6205 if (elType.equals("image")) {
6206 String elName = element.attributeValue(
6207 "name", StringPool.BLANK);
6208 String elIndex = element.attributeValue(
6209 "index", StringPool.BLANK);
6210
6211 String name = elName + StringPool.UNDERLINE + elIndex;
6212
6213 formatImage(
6214 groupId, articleId, version, incrementVersion, element,
6215 elInstanceId, name, images);
6216 }
6217 else if (elType.equals("text_area") || elType.equals("text") ||
6218 elType.equals("text_box")) {
6219
6220 List<Element> dynamicContentElements = element.elements(
6221 "dynamic-content");
6222
6223 for (Element dynamicContentElement : dynamicContentElements) {
6224 String dynamicContent = dynamicContentElement.getText();
6225
6226 if (Validator.isNotNull(dynamicContent)) {
6227 String contentType = ContentTypes.TEXT_PLAIN;
6228
6229 if (elType.equals("text_area")) {
6230 contentType = ContentTypes.TEXT_HTML;
6231 }
6232
6233 dynamicContent = SanitizerUtil.sanitize(
6234 user.getCompanyId(), groupId, user.getUserId(),
6235 JournalArticle.class.getName(), 0, contentType,
6236 dynamicContent);
6237
6238 dynamicContentElement.clearContent();
6239
6240 dynamicContentElement.addCDATA(dynamicContent);
6241 }
6242 }
6243 }
6244
6245 format(
6246 user, groupId, articleId, version, incrementVersion, element,
6247 images);
6248 }
6249 }
6250
6251 protected String format(
6252 User user, long groupId, String articleId, double version,
6253 boolean incrementVersion, String content, String ddmStructureKey,
6254 Map<String, byte[]> images)
6255 throws PortalException, SystemException {
6256
6257 Document document = null;
6258
6259 try {
6260 document = SAXReaderUtil.read(content);
6261
6262 Element rootElement = document.getRootElement();
6263
6264 if (Validator.isNotNull(ddmStructureKey)) {
6265 format(
6266 user, groupId, articleId, version, incrementVersion,
6267 rootElement, images);
6268 }
6269 else {
6270 List<Element> staticContentElements = rootElement.elements(
6271 "static-content");
6272
6273 for (Element staticContentElement : staticContentElements) {
6274 String staticContent = staticContentElement.getText();
6275
6276 staticContent = SanitizerUtil.sanitize(
6277 user.getCompanyId(), groupId, user.getUserId(),
6278 JournalArticle.class.getName(), 0,
6279 ContentTypes.TEXT_HTML, staticContent);
6280
6281 staticContentElement.clearContent();
6282
6283 staticContentElement.addCDATA(staticContent);
6284 }
6285 }
6286
6287 content = DDMXMLUtil.formatXML(document);
6288 }
6289 catch (DocumentException de) {
6290 _log.error(de, de);
6291 }
6292
6293 return content;
6294 }
6295
6296 protected void formatImage(
6297 long groupId, String articleId, double version,
6298 boolean incrementVersion, Element el, String elInstanceId,
6299 String elName, Map<String, byte[]> images)
6300 throws PortalException, SystemException {
6301
6302 List<Element> imageContents = el.elements("dynamic-content");
6303
6304 for (Element dynamicContent : imageContents) {
6305 String elLanguage = dynamicContent.attributeValue(
6306 "language-id", StringPool.BLANK);
6307
6308 if (!elLanguage.equals(StringPool.BLANK)) {
6309 elLanguage = StringPool.UNDERLINE + elLanguage;
6310 }
6311
6312 long imageId = journalArticleImageLocalService.getArticleImageId(
6313 groupId, articleId, version, elInstanceId, elName, elLanguage);
6314
6315 if (dynamicContent.getText().equals("delete") ||
6316 Validator.isNull(dynamicContent.getText())) {
6317
6318 dynamicContent.setText(StringPool.BLANK);
6319
6320 imageLocalService.deleteImage(imageId);
6321
6322 String defaultElLanguage = StringPool.BLANK;
6323
6324 if (Validator.isNull(elLanguage)) {
6325 defaultElLanguage =
6326 StringPool.UNDERLINE +
6327 LocaleUtil.toLanguageId(
6328 LocaleUtil.getSiteDefault());
6329 }
6330
6331 long defaultImageId =
6332 journalArticleImageLocalService.getArticleImageId(
6333 groupId, articleId, version, elInstanceId, elName,
6334 defaultElLanguage);
6335
6336 imageLocalService.deleteImage(defaultImageId);
6337
6338 continue;
6339 }
6340
6341 String elContent =
6342 "/image/journal/article?img_id=" + imageId + "&t=" +
6343 WebServerServletTokenUtil.getToken(imageId);
6344
6345 byte[] bytes = null;
6346
6347 if (images != null) {
6348 bytes = images.get(
6349 elInstanceId + StringPool.UNDERLINE + elName + elLanguage);
6350 }
6351
6352 Image image = imageLocalService.fetchImage(imageId);
6353
6354 String defaultElLanguage =
6355 StringPool.UNDERLINE +
6356 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6357
6358 if ((image == null) && ArrayUtil.isEmpty(bytes) &&
6359 !defaultElLanguage.equals(elLanguage)) {
6360
6361 Image oldImage = null;
6362
6363 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
6364 incrementVersion) {
6365
6366 oldImage = getPreviousVersionImage(
6367 version, groupId, articleId, elInstanceId, elName,
6368 elLanguage);
6369 }
6370
6371 if ((oldImage == null) && (images != null)) {
6372 bytes = images.get(
6373 elInstanceId + StringPool.UNDERLINE + elName +
6374 defaultElLanguage);
6375 }
6376 }
6377
6378 if (ArrayUtil.isNotEmpty(bytes)) {
6379 dynamicContent.setText(elContent);
6380 dynamicContent.addAttribute("id", String.valueOf(imageId));
6381
6382 imageLocalService.updateImage(imageId, bytes);
6383
6384 continue;
6385 }
6386
6387 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
6388 incrementVersion) {
6389
6390 Image oldImage = getPreviousVersionImage(
6391 version, groupId, articleId, elInstanceId, elName,
6392 elLanguage);
6393
6394 if (oldImage != null) {
6395 dynamicContent.setText(elContent);
6396 dynamicContent.addAttribute("id", String.valueOf(imageId));
6397
6398 bytes = oldImage.getTextObj();
6399
6400 imageLocalService.updateImage(imageId, bytes);
6401 }
6402 else if (dynamicContent.getText().equals("update")) {
6403 dynamicContent.setText(StringPool.BLANK);
6404 }
6405
6406 continue;
6407 }
6408
6409 if (image != null) {
6410 dynamicContent.setText(elContent);
6411 dynamicContent.addAttribute("id", String.valueOf(imageId));
6412
6413 continue;
6414 }
6415 else if (dynamicContent.getText().equals("update")) {
6416 dynamicContent.setText(StringPool.BLANK);
6417
6418 continue;
6419 }
6420
6421 long contentImageId = GetterUtil.getLong(
6422 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
6423
6424 if (contentImageId <= 0) {
6425 contentImageId = GetterUtil.getLong(
6426 HttpUtil.getParameter(
6427 dynamicContent.getText(), "img_id", false));
6428 }
6429
6430 if (contentImageId > 0) {
6431 image = imageLocalService.getImage(contentImageId);
6432
6433 if (image != null) {
6434 dynamicContent.addAttribute(
6435 "id", String.valueOf(contentImageId));
6436
6437 continue;
6438 }
6439 }
6440
6441 defaultElLanguage = StringPool.BLANK;
6442
6443 if (Validator.isNull(elLanguage)) {
6444 defaultElLanguage =
6445 StringPool.UNDERLINE +
6446 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6447 }
6448
6449 long defaultImageId =
6450 journalArticleImageLocalService.getArticleImageId(
6451 groupId, articleId, version, elInstanceId, elName,
6452 defaultElLanguage);
6453
6454 Image defaultImage = imageLocalService.getImage(defaultImageId);
6455
6456 if (defaultImage != null) {
6457 dynamicContent.setText(elContent);
6458 dynamicContent.addAttribute(
6459 "id", String.valueOf(defaultImageId));
6460
6461 bytes = defaultImage.getTextObj();
6462
6463 imageLocalService.updateImage(defaultImageId, bytes);
6464
6465 continue;
6466 }
6467
6468 if (Validator.isNotNull(elLanguage)) {
6469 dynamicContent.setText(StringPool.BLANK);
6470 }
6471 }
6472 }
6473
6474 protected Locale getArticleDefaultLocale(
6475 String content, ServiceContext serviceContext) {
6476
6477 String defaultLanguageId = ParamUtil.getString(
6478 serviceContext, "defaultLanguageId");
6479
6480 if (Validator.isNull(defaultLanguageId)) {
6481 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
6482 }
6483
6484 if (Validator.isNotNull(defaultLanguageId)) {
6485 return LocaleUtil.fromLanguageId(defaultLanguageId);
6486 }
6487
6488 return LocaleUtil.getSiteDefault();
6489 }
6490
6491 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
6492 List<JournalArticle> articles) {
6493
6494 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
6495 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
6496
6497 for (JournalArticle article : articles) {
6498 int status = article.getStatus();
6499
6500 if (status == WorkflowConstants.STATUS_PENDING) {
6501 status = WorkflowConstants.STATUS_DRAFT;
6502 }
6503
6504 ObjectValuePair<Long, Integer> articleVersionStatusOVP =
6505 new ObjectValuePair<Long, Integer>(article.getId(), status);
6506
6507 articleVersionStatusOVPs.add(articleVersionStatusOVP);
6508 }
6509
6510 return articleVersionStatusOVPs;
6511 }
6512
6513 protected long getClassTypeId(JournalArticle article) {
6514 long classTypeId = 0;
6515
6516 try {
6517 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
6518
6519 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6520 article.getGroupId(), classNameId, article.getStructureId());
6521
6522 if (ddmStructure == null) {
6523 Group companyGroup = groupLocalService.getCompanyGroup(
6524 article.getCompanyId());
6525
6526 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6527 companyGroup.getGroupId(), classNameId,
6528 article.getStructureId());
6529 }
6530
6531 if (ddmStructure != null) {
6532 classTypeId = ddmStructure.getStructureId();
6533 }
6534 }
6535 catch (Exception e) {
6536 _log.error(e, e);
6537 }
6538
6539 return classTypeId;
6540 }
6541
6542 protected JournalArticle getFirstArticle(
6543 long groupId, String articleId, int status,
6544 OrderByComparator orderByComparator)
6545 throws PortalException, SystemException {
6546
6547 if (status == WorkflowConstants.STATUS_ANY) {
6548 return journalArticlePersistence.findByG_A_NotST_First(
6549 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
6550 orderByComparator);
6551 }
6552 else {
6553 return journalArticlePersistence.findByG_A_ST_First(
6554 groupId, articleId, status, orderByComparator);
6555 }
6556 }
6557
6558 protected Image getPreviousVersionImage(
6559 double version, long groupId, String articleId, String elInstanceId,
6560 String elName, String elLanguage)
6561 throws PortalException, SystemException {
6562
6563 double oldVersion = getLatestVersion(groupId, articleId);
6564
6565 long oldImageId = journalArticleImageLocalService.getArticleImageId(
6566 groupId, articleId, oldVersion, elInstanceId, elName, elLanguage);
6567
6568 Image oldImage = null;
6569
6570 if (oldImageId > 0) {
6571 oldImage = imageLocalService.fetchImage(oldImageId);
6572 }
6573
6574 return oldImage;
6575 }
6576
6577 protected double getNextVersion(JournalArticle article)
6578 throws PortalException, SystemException {
6579
6580 double nextVersion = article.getVersion();
6581
6582
6583
6584
6585 JournalArticle latestLiveArticle = fetchLatestLiveArticle(article);
6586
6587 if ((latestLiveArticle != null) &&
6588 (latestLiveArticle.getVersion() > nextVersion)) {
6589
6590 nextVersion = latestLiveArticle.getVersion();
6591 }
6592
6593 return MathUtil.format(nextVersion + 0.1, 1, 1);
6594 }
6595
6596 protected String getUniqueUrlTitle(
6597 long id, long groupId, String articleId, String title)
6598 throws PortalException, SystemException {
6599
6600 String urlTitle = JournalUtil.getUrlTitle(id, title);
6601
6602 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6603 }
6604
6605 protected String getUniqueUrlTitle(
6606 long id, String articleId, String title, String oldUrlTitle,
6607 ServiceContext serviceContext)
6608 throws PortalException, SystemException {
6609
6610 String serviceContextUrlTitle = ParamUtil.getString(
6611 serviceContext, "urlTitle");
6612
6613 String urlTitle = null;
6614
6615 if (Validator.isNotNull(serviceContextUrlTitle)) {
6616 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6617 }
6618 else if (Validator.isNotNull(oldUrlTitle)) {
6619 return oldUrlTitle;
6620 }
6621 else {
6622 urlTitle = getUniqueUrlTitle(
6623 id, serviceContext.getScopeGroupId(), articleId, title);
6624 }
6625
6626 JournalArticle urlTitleArticle = fetchArticleByUrlTitle(
6627 serviceContext.getScopeGroupId(), urlTitle);
6628
6629 if ((urlTitleArticle != null) &&
6630 !Validator.equals(
6631 urlTitleArticle.getArticleId(), articleId)) {
6632
6633 urlTitle = getUniqueUrlTitle(
6634 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6635 }
6636
6637 return urlTitle;
6638 }
6639
6640 protected boolean hasModifiedLatestApprovedVersion(
6641 long groupId, String articleId, double version)
6642 throws SystemException {
6643
6644 JournalArticle article = fetchLatestArticle(
6645 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6646
6647 if ((article == null) || (article.getVersion() <= version)) {
6648 return true;
6649 }
6650
6651 return false;
6652 }
6653
6654 protected void notifySubscribers(
6655 JournalArticle article, ServiceContext serviceContext)
6656 throws PortalException, SystemException {
6657
6658 if (!article.isApproved()) {
6659 return;
6660 }
6661
6662 String articleURL = PortalUtil.getControlPanelFullURL(
6663 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6664
6665 if (Validator.isNull(articleURL)) {
6666 return;
6667 }
6668
6669 articleURL = buildArticleURL(
6670 articleURL, article.getGroupId(), article.getFolderId(),
6671 article.getArticleId());
6672
6673 PortletPreferences preferences =
6674 ServiceContextUtil.getPortletPreferences(serviceContext);
6675
6676 if (preferences == null) {
6677 long ownerId = article.getGroupId();
6678 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6679 long plid = PortletKeys.PREFS_PLID_SHARED;
6680 String portletId = PortletKeys.JOURNAL;
6681 String defaultPreferences = null;
6682
6683 preferences = portletPreferencesLocalService.getPreferences(
6684 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6685 defaultPreferences);
6686 }
6687
6688 if ((article.getVersion() == 1.0) &&
6689 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6690 }
6691 else if ((article.getVersion() != 1.0) &&
6692 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6693 }
6694 else {
6695 return;
6696 }
6697
6698 String fromName = JournalUtil.getEmailFromName(
6699 preferences, article.getCompanyId());
6700 String fromAddress = JournalUtil.getEmailFromAddress(
6701 preferences, article.getCompanyId());
6702
6703 String subject = null;
6704 String body = null;
6705
6706 if (article.getVersion() == 1.0) {
6707 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6708 body = JournalUtil.getEmailArticleAddedBody(preferences);
6709 }
6710 else {
6711 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6712 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6713 }
6714
6715 String articleContent = StringPool.BLANK;
6716
6717 try {
6718 String xmlRequest = PortletRequestUtil.toXML(
6719 serviceContext.getLiferayPortletRequest(),
6720 serviceContext.getLiferayPortletResponse());
6721
6722 JournalArticleDisplay articleDisplay = getArticleDisplay(
6723 article, null, Constants.VIEW,
6724 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault()), 1,
6725 xmlRequest, serviceContext.getThemeDisplay());
6726
6727 articleContent = articleDisplay.getContent();
6728 }
6729 catch (Exception e) {
6730 }
6731
6732 SubscriptionSender subscriptionSender = new SubscriptionSender();
6733
6734 subscriptionSender.setBody(body);
6735 subscriptionSender.setCompanyId(article.getCompanyId());
6736 subscriptionSender.setContextAttributes(
6737 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6738 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6739 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6740 subscriptionSender.setContextAttribute(
6741 "[$ARTICLE_CONTENT$]", articleContent, false);
6742 subscriptionSender.setContextUserPrefix("ARTICLE");
6743 subscriptionSender.setFrom(fromAddress, fromName);
6744 subscriptionSender.setHtmlFormat(true);
6745 subscriptionSender.setMailId("journal_article", article.getId());
6746 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6747 subscriptionSender.setReplyToAddress(fromAddress);
6748 subscriptionSender.setScopeGroupId(article.getGroupId());
6749 subscriptionSender.setServiceContext(serviceContext);
6750 subscriptionSender.setSubject(subject);
6751 subscriptionSender.setUserId(article.getUserId());
6752
6753 JournalFolder folder = article.getFolder();
6754
6755 List<Long> folderIds = new ArrayList<Long>();
6756
6757 if (folder != null) {
6758 folderIds.add(folder.getFolderId());
6759
6760 folderIds.addAll(folder.getAncestorFolderIds());
6761 }
6762
6763 for (long curFolderId : folderIds) {
6764 subscriptionSender.addPersistedSubscribers(
6765 JournalFolder.class.getName(), curFolderId);
6766 }
6767
6768 subscriptionSender.addPersistedSubscribers(
6769 JournalArticle.class.getName(), article.getGroupId());
6770
6771 subscriptionSender.addPersistedSubscribers(
6772 JournalArticle.class.getName(), article.getResourcePrimKey());
6773
6774 subscriptionSender.flushNotificationsAsync();
6775 }
6776
6777 protected void saveImages(
6778 boolean smallImage, long smallImageId, File smallImageFile,
6779 byte[] smallImageBytes)
6780 throws PortalException, SystemException {
6781
6782 if (smallImage) {
6783 if ((smallImageFile != null) && (smallImageBytes != null)) {
6784 imageLocalService.updateImage(smallImageId, smallImageBytes);
6785 }
6786 }
6787 else {
6788 imageLocalService.deleteImage(smallImageId);
6789 }
6790 }
6791
6792 protected void sendEmail(
6793 JournalArticle article, String articleURL,
6794 PortletPreferences preferences, String emailType,
6795 ServiceContext serviceContext)
6796 throws PortalException, SystemException {
6797
6798 if (preferences == null) {
6799 return;
6800 }
6801 else if (emailType.equals("denied") &&
6802 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6803 preferences)) {
6804 }
6805 else if (emailType.equals("granted") &&
6806 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6807 preferences)) {
6808 }
6809 else if (emailType.equals("requested") &&
6810 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6811 preferences)) {
6812 }
6813 else if (emailType.equals("review") &&
6814 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6815 }
6816 else {
6817 return;
6818 }
6819
6820 Company company = companyPersistence.findByPrimaryKey(
6821 article.getCompanyId());
6822
6823 User user = userPersistence.findByPrimaryKey(article.getUserId());
6824
6825 String fromName = JournalUtil.getEmailFromName(
6826 preferences, article.getCompanyId());
6827 String fromAddress = JournalUtil.getEmailFromAddress(
6828 preferences, article.getCompanyId());
6829
6830 String toName = user.getFullName();
6831 String toAddress = user.getEmailAddress();
6832
6833 if (emailType.equals("requested")) {
6834 String tempToName = fromName;
6835 String tempToAddress = fromAddress;
6836
6837 fromName = toName;
6838 fromAddress = toAddress;
6839
6840 toName = tempToName;
6841 toAddress = tempToAddress;
6842 }
6843
6844 String subject = null;
6845 String body = null;
6846
6847 if (emailType.equals("denied")) {
6848 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6849 preferences);
6850 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6851 }
6852 else if (emailType.equals("granted")) {
6853 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6854 preferences);
6855 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6856 }
6857 else if (emailType.equals("requested")) {
6858 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6859 preferences);
6860 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6861 preferences);
6862 }
6863 else if (emailType.equals("review")) {
6864 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6865 body = JournalUtil.getEmailArticleReviewBody(preferences);
6866 }
6867
6868 SubscriptionSender subscriptionSender = new SubscriptionSender();
6869
6870 subscriptionSender.setBody(body);
6871 subscriptionSender.setCompanyId(company.getCompanyId());
6872 subscriptionSender.setContextAttributes(
6873 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6874 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6875 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6876 "[$ARTICLE_VERSION$]", article.getVersion());
6877 subscriptionSender.setContextUserPrefix("ARTICLE");
6878 subscriptionSender.setFrom(fromAddress, fromName);
6879 subscriptionSender.setHtmlFormat(true);
6880 subscriptionSender.setMailId("journal_article", article.getId());
6881 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6882 subscriptionSender.setScopeGroupId(article.getGroupId());
6883 subscriptionSender.setServiceContext(serviceContext);
6884 subscriptionSender.setSubject(subject);
6885 subscriptionSender.setUserId(article.getUserId());
6886
6887 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6888
6889 subscriptionSender.flushNotificationsAsync();
6890 }
6891
6892 protected void updateDDMStructureXSD(
6893 long ddmStructureId, String content, ServiceContext serviceContext)
6894 throws PortalException, SystemException {
6895
6896 boolean indexingEnabled = serviceContext.isIndexingEnabled();
6897
6898 try {
6899 DDMStructure ddmStructure =
6900 ddmStructureLocalService.fetchDDMStructure(ddmStructureId);
6901
6902 if (ddmStructure == null) {
6903 return;
6904 }
6905
6906 Document documentXSD = SAXReaderUtil.read(ddmStructure.getXsd());
6907
6908 Document document = SAXReaderUtil.read(content);
6909
6910 Element rootElement = document.getRootElement();
6911
6912 List<Element> elements = rootElement.elements();
6913
6914 for (Element element : elements) {
6915 String fieldName = element.attributeValue(
6916 "name", StringPool.BLANK);
6917
6918 List<Element> dynamicContentElements = element.elements(
6919 "dynamic-content");
6920
6921 for (Element dynamicContentElement : dynamicContentElements) {
6922 String value = dynamicContentElement.getText();
6923
6924 documentXSD = updateDDMStructureXSDFieldMetadata(
6925 documentXSD, fieldName, FieldConstants.PREDEFINED_VALUE,
6926 value);
6927 }
6928 }
6929
6930 serviceContext.setIndexingEnabled(false);
6931
6932 ddmStructureLocalService.updateXSD(
6933 ddmStructureId, documentXSD.asXML(), serviceContext);
6934 }
6935 catch (DocumentException de) {
6936 throw new SystemException(de);
6937 }
6938 finally {
6939 serviceContext.setIndexingEnabled(indexingEnabled);
6940 }
6941 }
6942
6943 protected Document updateDDMStructureXSDFieldMetadata(
6944 Document document, String fieldName, String metadataEntryName,
6945 String metadataEntryValue)
6946 throws DocumentException {
6947
6948 Element rootElement = document.getRootElement();
6949
6950 List<Element> dynamicElementElements = rootElement.elements(
6951 "dynamic-element");
6952
6953 for (Element dynamicElementElement : dynamicElementElements) {
6954 String dynamicElementElementFieldName = GetterUtil.getString(
6955 dynamicElementElement.attributeValue("name"));
6956
6957 if (!dynamicElementElementFieldName.equals(fieldName)) {
6958 continue;
6959 }
6960
6961 List<Element> metadataElements = dynamicElementElement.elements(
6962 "meta-data");
6963
6964 for (Element metadataElement : metadataElements) {
6965 List<Element> metadataEntryElements =
6966 metadataElement.elements();
6967
6968 for (Element metadataEntryElement : metadataEntryElements) {
6969 String metadataEntryElementName = GetterUtil.getString(
6970 metadataEntryElement.attributeValue("name"));
6971
6972 if (metadataEntryElementName.equals(metadataEntryName)) {
6973 metadataEntryElement.setText(metadataEntryValue);
6974 }
6975 }
6976 }
6977 }
6978
6979 return document;
6980 }
6981
6982 protected void updatePreviousApprovedArticle(JournalArticle article)
6983 throws PortalException, SystemException {
6984
6985 List<JournalArticle> approvedArticles =
6986 journalArticlePersistence.findByG_A_ST(
6987 article.getGroupId(), article.getArticleId(),
6988 WorkflowConstants.STATUS_APPROVED, 0, 2);
6989
6990 if (approvedArticles.isEmpty() ||
6991 ((approvedArticles.size() == 1) &&
6992 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6993
6994 assetEntryLocalService.updateVisible(
6995 JournalArticle.class.getName(), article.getResourcePrimKey(),
6996 false);
6997 }
6998 else {
6999 JournalArticle previousApprovedArticle = approvedArticles.get(0);
7000
7001 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
7002 previousApprovedArticle = approvedArticles.get(1);
7003 }
7004
7005 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
7006 JournalArticle.class.getName(), article.getResourcePrimKey(),
7007 previousApprovedArticle.getDisplayDate(),
7008 previousApprovedArticle.getExpirationDate(), true);
7009
7010 assetEntry.setModifiedDate(
7011 previousApprovedArticle.getModifiedDate());
7012 assetEntry.setTitle(previousApprovedArticle.getTitle());
7013
7014 assetEntryPersistence.update(assetEntry);
7015 }
7016 }
7017
7018 protected void updateUrlTitles(
7019 long groupId, String articleId, String urlTitle)
7020 throws PortalException, SystemException {
7021
7022 JournalArticle firstArticle = journalArticlePersistence.findByG_A_First(
7023 groupId, articleId, new ArticleVersionComparator(false));
7024
7025 if (firstArticle.getUrlTitle().equals(urlTitle)) {
7026 return;
7027 }
7028
7029 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
7030 groupId, articleId);
7031
7032 for (JournalArticle article : articles) {
7033 if (!article.getUrlTitle().equals(urlTitle)) {
7034 article.setUrlTitle(urlTitle);
7035
7036 journalArticlePersistence.update(article);
7037 }
7038 }
7039 }
7040
7041 protected void validate(
7042 long companyId, long groupId, long classNameId,
7043 Map<Locale, String> titleMap, String content, String type,
7044 String ddmStructureKey, String ddmTemplateKey, Date displayDate,
7045 Date expirationDate, boolean smallImage, String smallImageURL,
7046 File smallImageFile, byte[] smallImageBytes,
7047 ServiceContext serviceContext)
7048 throws PortalException, SystemException {
7049
7050 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
7051 LocalizationUtil.getDefaultLanguageId(content));
7052
7053 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
7054
7055 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale) &&
7056 !ExportImportThreadLocal.isImportInProcess()) {
7057
7058 LocaleException le = new LocaleException(
7059 LocaleException.TYPE_CONTENT,
7060 "The locale " + articleDefaultLocale +
7061 " is not available in site with groupId" + groupId);
7062
7063 Locale[] sourceAvailableLocales = {articleDefaultLocale};
7064
7065 le.setSourceAvailableLocales(sourceAvailableLocales);
7066 le.setTargetAvailableLocales(availableLocales);
7067
7068 throw le;
7069 }
7070
7071 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
7072 (titleMap.isEmpty() ||
7073 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
7074
7075 throw new ArticleTitleException();
7076 }
7077 else if (Validator.isNull(type)) {
7078 throw new ArticleTypeException();
7079 }
7080
7081 validateContent(content);
7082
7083 if (Validator.isNotNull(ddmStructureKey)) {
7084 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7085 PortalUtil.getSiteGroupId(groupId),
7086 PortalUtil.getClassNameId(JournalArticle.class),
7087 ddmStructureKey, true);
7088
7089 validateDDMStructureFields(
7090 ddmStructure, classNameId, content, articleDefaultLocale);
7091
7092 if (Validator.isNotNull(ddmTemplateKey)) {
7093 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
7094 PortalUtil.getSiteGroupId(groupId),
7095 PortalUtil.getClassNameId(DDMStructure.class),
7096 ddmTemplateKey, true);
7097
7098 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
7099 throw new NoSuchTemplateException(
7100 "{templateKey=" + ddmTemplateKey + "}");
7101 }
7102 }
7103 else if (classNameId ==
7104 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
7105
7106 throw new NoSuchTemplateException();
7107 }
7108 }
7109
7110 if ((expirationDate != null) && (expirationDate.before(new Date()) ||
7111 ((displayDate != null) && expirationDate.before(displayDate))) &&
7112 !ExportImportThreadLocal.isImportInProcess()) {
7113
7114 throw new ArticleExpirationDateException();
7115 }
7116
7117 if (smallImage && Validator.isNull(smallImageURL) &&
7118 ArrayUtil.isEmpty(smallImageBytes)) {
7119
7120 throw new NoSuchArticleImageException();
7121 }
7122
7123 String[] imageExtensions = PrefsPropsUtil.getStringArray(
7124 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
7125
7126 if (!smallImage || Validator.isNotNull(smallImageURL) ||
7127 (smallImageFile == null) || (smallImageBytes == null)) {
7128
7129 return;
7130 }
7131
7132 String smallImageName = smallImageFile.getName();
7133
7134 if (smallImageName != null) {
7135 boolean validSmallImageExtension = false;
7136
7137 for (String _imageExtension : imageExtensions) {
7138 if (StringPool.STAR.equals(_imageExtension) ||
7139 StringUtil.endsWith(smallImageName, _imageExtension)) {
7140
7141 validSmallImageExtension = true;
7142
7143 break;
7144 }
7145 }
7146
7147 if (!validSmallImageExtension) {
7148 throw new ArticleSmallImageNameException(smallImageName);
7149 }
7150 }
7151
7152 long smallImageMaxSize = PrefsPropsUtil.getLong(
7153 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
7154
7155 if ((smallImageMaxSize > 0) &&
7156 ((smallImageBytes == null) ||
7157 (smallImageBytes.length > smallImageMaxSize))) {
7158
7159 throw new ArticleSmallImageSizeException();
7160 }
7161 }
7162
7163 protected void validate(
7164 long companyId, long groupId, long classNameId, String articleId,
7165 boolean autoArticleId, double version, Map<Locale, String> titleMap,
7166 String content, String type, String ddmStructureKey,
7167 String ddmTemplateKey, Date displayDate, Date expirationDate,
7168 boolean smallImage, String smallImageURL, File smallImageFile,
7169 byte[] smallImageBytes, ServiceContext serviceContext)
7170 throws PortalException, SystemException {
7171
7172 if (!autoArticleId) {
7173 validate(articleId);
7174 }
7175
7176 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
7177 groupId, articleId, version);
7178
7179 if (article != null) {
7180 StringBundler sb = new StringBundler(7);
7181
7182 sb.append("{groupId=");
7183 sb.append(groupId);
7184 sb.append(", articleId=");
7185 sb.append(articleId);
7186 sb.append(", version=");
7187 sb.append(version);
7188 sb.append("}");
7189
7190 throw new DuplicateArticleIdException(sb.toString());
7191 }
7192
7193 validate(
7194 companyId, groupId, classNameId, titleMap, content, type,
7195 ddmStructureKey, ddmTemplateKey, displayDate, expirationDate,
7196 smallImage, smallImageURL, smallImageFile, smallImageBytes,
7197 serviceContext);
7198 }
7199
7200 protected void validate(String articleId) throws PortalException {
7201 if (Validator.isNull(articleId) ||
7202 (articleId.indexOf(CharPool.COMMA) != -1) ||
7203 (articleId.indexOf(CharPool.SPACE) != -1)) {
7204
7205 throw new ArticleIdException();
7206 }
7207 }
7208
7209 protected void validateContent(String content) throws PortalException {
7210 if (Validator.isNull(content)) {
7211 throw new ArticleContentException("Content is null");
7212 }
7213
7214 try {
7215 SAXReaderUtil.read(content);
7216 }
7217 catch (DocumentException de) {
7218 if (_log.isDebugEnabled()) {
7219 _log.debug("Invalid content:\n" + content);
7220 }
7221
7222 throw new ArticleContentException(
7223 "Unable to read content with an XML parser", de);
7224 }
7225 }
7226
7227 protected void validateDDMStructureFields(
7228 DDMStructure ddmStructure, long classNameId, Fields fields,
7229 Locale defaultLocale)
7230 throws PortalException, SystemException {
7231
7232 for (com.liferay.portlet.dynamicdatamapping.storage.Field field :
7233 fields) {
7234
7235 if (!ddmStructure.hasField(field.getName())) {
7236 throw new StorageFieldNameException();
7237 }
7238
7239 if (ddmStructure.getFieldRequired(field.getName()) &&
7240 Validator.isNull(field.getValue(defaultLocale)) &&
7241 (classNameId ==
7242 JournalArticleConstants.CLASSNAME_ID_DEFAULT)) {
7243
7244 StringBundler sb = new StringBundler(6);
7245
7246 sb.append("Required field ");
7247 sb.append(field.getName());
7248 sb.append(" is not present for structure ");
7249 sb.append(ddmStructure.getNameCurrentValue());
7250 sb.append(" for locale ");
7251 sb.append(defaultLocale);
7252
7253 throw new StorageFieldRequiredException(sb.toString());
7254 }
7255 }
7256 }
7257
7258 protected void validateDDMStructureFields(
7259 DDMStructure ddmStructure, long classNameId,
7260 ServiceContext serviceContext, Locale defaultLocale)
7261 throws PortalException, SystemException {
7262
7263 Fields fields = DDMUtil.getFields(
7264 ddmStructure.getStructureId(), serviceContext);
7265
7266 validateDDMStructureFields(
7267 ddmStructure, classNameId, fields, defaultLocale);
7268 }
7269
7270 protected void validateDDMStructureFields(
7271 DDMStructure ddmStructure, long classNameId, String content,
7272 Locale defaultLocale)
7273 throws PortalException, SystemException {
7274
7275 Fields fields;
7276
7277 try {
7278 fields = JournalConverterUtil.getDDMFields(ddmStructure, content);
7279 }
7280 catch (Exception e) {
7281 if (e instanceof PortalException) {
7282 throw new PortalException(e);
7283 }
7284 else {
7285 throw new SystemException(e);
7286 }
7287 }
7288
7289 validateDDMStructureFields(
7290 ddmStructure, classNameId, fields, defaultLocale);
7291 }
7292
7293 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
7294 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
7295
7296 private static Log _log = LogFactoryUtil.getLog(
7297 JournalArticleLocalServiceImpl.class);
7298
7299 private Date _previousCheckDate;
7300
7301 }