001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.NoSuchImageException;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
024 import com.liferay.portal.kernel.search.Field;
025 import com.liferay.portal.kernel.search.Hits;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.search.QueryConfig;
029 import com.liferay.portal.kernel.search.SearchContext;
030 import com.liferay.portal.kernel.search.Sort;
031 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
032 import com.liferay.portal.kernel.util.CharPool;
033 import com.liferay.portal.kernel.util.ContentTypes;
034 import com.liferay.portal.kernel.util.FileUtil;
035 import com.liferay.portal.kernel.util.GetterUtil;
036 import com.liferay.portal.kernel.util.HtmlUtil;
037 import com.liferay.portal.kernel.util.HttpUtil;
038 import com.liferay.portal.kernel.util.ListUtil;
039 import com.liferay.portal.kernel.util.LocaleUtil;
040 import com.liferay.portal.kernel.util.LocalizationUtil;
041 import com.liferay.portal.kernel.util.MathUtil;
042 import com.liferay.portal.kernel.util.OrderByComparator;
043 import com.liferay.portal.kernel.util.PropsKeys;
044 import com.liferay.portal.kernel.util.StringPool;
045 import com.liferay.portal.kernel.util.StringUtil;
046 import com.liferay.portal.kernel.util.Time;
047 import com.liferay.portal.kernel.util.Validator;
048 import com.liferay.portal.kernel.workflow.WorkflowConstants;
049 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
050 import com.liferay.portal.kernel.xml.Document;
051 import com.liferay.portal.kernel.xml.DocumentException;
052 import com.liferay.portal.kernel.xml.Element;
053 import com.liferay.portal.kernel.xml.Node;
054 import com.liferay.portal.kernel.xml.SAXReaderUtil;
055 import com.liferay.portal.kernel.xml.XPath;
056 import com.liferay.portal.model.Company;
057 import com.liferay.portal.model.Group;
058 import com.liferay.portal.model.Image;
059 import com.liferay.portal.model.ModelHintsUtil;
060 import com.liferay.portal.model.ResourceConstants;
061 import com.liferay.portal.model.User;
062 import com.liferay.portal.service.ServiceContext;
063 import com.liferay.portal.service.ServiceContextUtil;
064 import com.liferay.portal.servlet.filters.cache.CacheUtil;
065 import com.liferay.portal.theme.ThemeDisplay;
066 import com.liferay.portal.util.PortalUtil;
067 import com.liferay.portal.util.PortletKeys;
068 import com.liferay.portal.util.PrefsPropsUtil;
069 import com.liferay.portal.util.PropsValues;
070 import com.liferay.portal.util.SubscriptionSender;
071 import com.liferay.portal.webserver.WebServerServletTokenUtil;
072 import com.liferay.portlet.asset.NoSuchEntryException;
073 import com.liferay.portlet.asset.model.AssetEntry;
074 import com.liferay.portlet.asset.model.AssetLink;
075 import com.liferay.portlet.asset.model.AssetLinkConstants;
076 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
077 import com.liferay.portlet.expando.model.ExpandoBridge;
078 import com.liferay.portlet.journal.ArticleContentException;
079 import com.liferay.portlet.journal.ArticleDisplayDateException;
080 import com.liferay.portlet.journal.ArticleExpirationDateException;
081 import com.liferay.portlet.journal.ArticleIdException;
082 import com.liferay.portlet.journal.ArticleReviewDateException;
083 import com.liferay.portlet.journal.ArticleSmallImageNameException;
084 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
085 import com.liferay.portlet.journal.ArticleTitleException;
086 import com.liferay.portlet.journal.ArticleTypeException;
087 import com.liferay.portlet.journal.ArticleVersionException;
088 import com.liferay.portlet.journal.DuplicateArticleIdException;
089 import com.liferay.portlet.journal.NoSuchArticleException;
090 import com.liferay.portlet.journal.NoSuchArticleResourceException;
091 import com.liferay.portlet.journal.NoSuchStructureException;
092 import com.liferay.portlet.journal.NoSuchTemplateException;
093 import com.liferay.portlet.journal.StructureXsdException;
094 import com.liferay.portlet.journal.model.JournalArticle;
095 import com.liferay.portlet.journal.model.JournalArticleConstants;
096 import com.liferay.portlet.journal.model.JournalArticleDisplay;
097 import com.liferay.portlet.journal.model.JournalArticleResource;
098 import com.liferay.portlet.journal.model.JournalStructure;
099 import com.liferay.portlet.journal.model.JournalTemplate;
100 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
101 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
102 import com.liferay.portlet.journal.util.JournalUtil;
103 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
104 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
105 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
106
107 import java.io.File;
108 import java.io.IOException;
109 import java.io.Serializable;
110
111 import java.util.Calendar;
112 import java.util.Date;
113 import java.util.HashMap;
114 import java.util.HashSet;
115 import java.util.LinkedHashMap;
116 import java.util.List;
117 import java.util.Locale;
118 import java.util.Map;
119 import java.util.Set;
120
121 import javax.portlet.PortletPreferences;
122
123
129 public class JournalArticleLocalServiceImpl
130 extends JournalArticleLocalServiceBaseImpl {
131
132 public JournalArticle addArticle(
133 long userId, long groupId, long classNameId, long classPK,
134 String articleId, boolean autoArticleId, double version,
135 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
136 String content, String type, String structureId, String templateId,
137 String layoutUuid, int displayDateMonth, int displayDateDay,
138 int displayDateYear, int displayDateHour, int displayDateMinute,
139 int expirationDateMonth, int expirationDateDay,
140 int expirationDateYear, int expirationDateHour,
141 int expirationDateMinute, boolean neverExpire, int reviewDateMonth,
142 int reviewDateDay, int reviewDateYear, int reviewDateHour,
143 int reviewDateMinute, boolean neverReview, boolean indexable,
144 boolean smallImage, String smallImageURL, File smallImageFile,
145 Map<String, byte[]> images, String articleURL,
146 ServiceContext serviceContext)
147 throws PortalException, SystemException {
148
149
150
151 User user = userPersistence.findByPrimaryKey(userId);
152 articleId = articleId.trim().toUpperCase();
153
154 Date displayDate = PortalUtil.getDate(
155 displayDateMonth, displayDateDay, displayDateYear,
156 displayDateHour, displayDateMinute, user.getTimeZone(),
157 new ArticleDisplayDateException());
158
159 Date expirationDate = null;
160
161 if (!neverExpire) {
162 expirationDate = PortalUtil.getDate(
163 expirationDateMonth, expirationDateDay, expirationDateYear,
164 expirationDateHour, expirationDateMinute, user.getTimeZone(),
165 new ArticleExpirationDateException());
166 }
167
168 Date reviewDate = null;
169
170 if (!neverReview) {
171 reviewDate = PortalUtil.getDate(
172 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
173 reviewDateMinute, user.getTimeZone(),
174 new ArticleReviewDateException());
175 }
176
177 byte[] smallImageBytes = null;
178
179 try {
180 smallImageBytes = FileUtil.getBytes(smallImageFile);
181 }
182 catch (IOException ioe) {
183 }
184
185 Date now = new Date();
186
187 validate(
188 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
189 version, titleMap, content, type, structureId, templateId,
190 smallImage, smallImageURL, smallImageFile, smallImageBytes);
191
192 if (autoArticleId) {
193 articleId = String.valueOf(counterLocalService.increment());
194 }
195
196 long id = counterLocalService.increment();
197
198 long resourcePrimKey =
199 journalArticleResourceLocalService.getArticleResourcePrimKey(
200 serviceContext.getUuid(), groupId, articleId);
201
202 JournalArticle article = journalArticlePersistence.create(id);
203
204 Locale locale = LocaleUtil.getDefault();
205
206 String defaultLanguageId = GetterUtil.getString(
207 serviceContext.getAttribute("defaultLanguageId"));
208
209 if (Validator.isNotNull(defaultLanguageId)) {
210 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
211 }
212
213 String title = titleMap.get(locale);
214
215 content = format(
216 user, groupId, articleId, version, false, content, structureId,
217 images);
218
219 article.setResourcePrimKey(resourcePrimKey);
220 article.setGroupId(groupId);
221 article.setCompanyId(user.getCompanyId());
222 article.setUserId(user.getUserId());
223 article.setUserName(user.getFullName());
224 article.setCreateDate(serviceContext.getCreateDate(now));
225 article.setModifiedDate(serviceContext.getModifiedDate(now));
226 article.setClassNameId(classNameId);
227 article.setClassPK(classPK);
228 article.setArticleId(articleId);
229 article.setVersion(version);
230 article.setTitleMap(titleMap, locale);
231 article.setUrlTitle(getUniqueUrlTitle(id, groupId, articleId, title));
232 article.setDescriptionMap(descriptionMap, locale);
233 article.setContent(content);
234 article.setType(type);
235 article.setStructureId(structureId);
236 article.setTemplateId(templateId);
237 article.setLayoutUuid(layoutUuid);
238 article.setDisplayDate(displayDate);
239 article.setExpirationDate(expirationDate);
240 article.setReviewDate(reviewDate);
241 article.setIndexable(indexable);
242 article.setSmallImage(smallImage);
243 article.setSmallImageId(counterLocalService.increment());
244 article.setSmallImageURL(smallImageURL);
245
246 if ((expirationDate == null) || expirationDate.after(now)) {
247 article.setStatus(WorkflowConstants.STATUS_DRAFT);
248 }
249 else {
250 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
251 }
252
253 journalArticlePersistence.update(article, false);
254
255
256
257 if (serviceContext.isAddGroupPermissions() ||
258 serviceContext.isAddGuestPermissions()) {
259
260 addArticleResources(
261 article, serviceContext.isAddGroupPermissions(),
262 serviceContext.isAddGuestPermissions());
263 }
264 else {
265 addArticleResources(
266 article, serviceContext.getGroupPermissions(),
267 serviceContext.getGuestPermissions());
268 }
269
270
271
272 ExpandoBridge expandoBridge = article.getExpandoBridge();
273
274 expandoBridge.setAttributes(serviceContext);
275
276
277
278 saveImages(
279 smallImage, article.getSmallImageId(), smallImageFile,
280 smallImageBytes);
281
282
283
284 updateAsset(
285 userId, article, serviceContext.getAssetCategoryIds(),
286 serviceContext.getAssetTagNames(),
287 serviceContext.getAssetLinkEntryIds());
288
289
290
291 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
292 mbMessageLocalService.addDiscussionMessage(
293 userId, article.getUserName(), groupId,
294 JournalArticle.class.getName(), resourcePrimKey,
295 WorkflowConstants.ACTION_PUBLISH);
296 }
297
298
299
300 PortletPreferences preferences =
301 ServiceContextUtil.getPortletPreferences(serviceContext);
302
303 sendEmail(
304 article, articleURL, preferences, "requested", serviceContext);
305
306
307
308 if (classNameId == 0) {
309 WorkflowHandlerRegistryUtil.startWorkflowInstance(
310 user.getCompanyId(), groupId, userId,
311 JournalArticle.class.getName(), article.getId(), article,
312 serviceContext);
313
314 if (serviceContext.getWorkflowAction() !=
315 WorkflowConstants.ACTION_PUBLISH) {
316
317
318
319 Indexer indexer = IndexerRegistryUtil.getIndexer(
320 JournalArticle.class);
321
322 indexer.reindex(article);
323 }
324 }
325 else {
326 updateStatus(
327 userId, article, WorkflowConstants.STATUS_APPROVED, null,
328 serviceContext);
329 }
330
331 return article;
332 }
333
334 public void addArticleResources(
335 JournalArticle article, boolean addGroupPermissions,
336 boolean addGuestPermissions)
337 throws PortalException, SystemException {
338
339 resourceLocalService.addResources(
340 article.getCompanyId(), article.getGroupId(),
341 article.getUserId(), JournalArticle.class.getName(),
342 article.getResourcePrimKey(), false, addGroupPermissions,
343 addGuestPermissions);
344 }
345
346 public void addArticleResources(
347 JournalArticle article, String[] groupPermissions,
348 String[] guestPermissions)
349 throws PortalException, SystemException {
350
351 resourceLocalService.addModelResources(
352 article.getCompanyId(), article.getGroupId(),
353 article.getUserId(), JournalArticle.class.getName(),
354 article.getResourcePrimKey(), groupPermissions, guestPermissions);
355 }
356
357 public void addArticleResources(
358 long groupId, String articleId, boolean addGroupPermissions,
359 boolean addGuestPermissions)
360 throws PortalException, SystemException {
361
362 JournalArticle article = getLatestArticle(groupId, articleId);
363
364 addArticleResources(article, addGroupPermissions, addGuestPermissions);
365 }
366
367 public void addArticleResources(
368 long groupId, String articleId, String[] groupPermissions,
369 String[] guestPermissions)
370 throws PortalException, SystemException {
371
372 JournalArticle article = getLatestArticle(groupId, articleId);
373
374 addArticleResources(article, groupPermissions, guestPermissions);
375 }
376
377 public JournalArticle checkArticleResourcePrimKey(
378 long groupId, String articleId, double version)
379 throws PortalException, SystemException {
380
381 JournalArticle article = journalArticlePersistence.findByG_A_V(
382 groupId, articleId, version);
383
384 if (article.getResourcePrimKey() > 0) {
385 return article;
386 }
387
388 long resourcePrimKey =
389 journalArticleResourceLocalService.getArticleResourcePrimKey(
390 groupId, articleId);
391
392 article.setResourcePrimKey(resourcePrimKey);
393
394 journalArticlePersistence.update(article, false);
395
396 return article;
397 }
398
399 public void checkArticles() throws PortalException, SystemException {
400 Date now = new Date();
401
402 List<JournalArticle> articles =
403 journalArticleFinder.findByExpirationDate(
404 0, WorkflowConstants.STATUS_APPROVED, now);
405
406 if (_log.isDebugEnabled()) {
407 _log.debug("Expiring " + articles.size() + " articles");
408 }
409
410 Set<Long> companyIds = new HashSet<Long>();
411
412 for (JournalArticle article : articles) {
413 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
414
415 journalArticlePersistence.update(article, false);
416
417 if (article.isIndexable()) {
418 Indexer indexer = IndexerRegistryUtil.getIndexer(
419 JournalArticle.class);
420
421 indexer.delete(article);
422 }
423
424 updatePreviousApprovedArticle(article);
425
426 JournalContentUtil.clearCache(
427 article.getGroupId(), article.getArticleId(),
428 article.getTemplateId());
429
430 companyIds.add(article.getCompanyId());
431 }
432
433 for (long companyId : companyIds) {
434 CacheUtil.clearCache(companyId);
435 }
436
437 articles = journalArticleFinder.findByReviewDate(
438 0, now, new Date(now.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL));
439
440 if (_log.isDebugEnabled()) {
441 _log.debug(
442 "Sending review notifications for " + articles.size() +
443 " articles");
444 }
445
446 for (JournalArticle article : articles) {
447 String articleURL = StringPool.BLANK;
448
449 long ownerId = article.getGroupId();
450 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
451 long plid = PortletKeys.PREFS_PLID_SHARED;
452 String portletId = PortletKeys.JOURNAL;
453
454 PortletPreferences preferences =
455 portletPreferencesLocalService.getPreferences(
456 article.getCompanyId(), ownerId, ownerType, plid,
457 portletId);
458
459 sendEmail(
460 article, articleURL, preferences, "review",
461 new ServiceContext());
462 }
463 }
464
465 public void checkNewLine(long groupId, String articleId, double version)
466 throws PortalException, SystemException {
467
468 JournalArticle article = journalArticlePersistence.findByG_A_V(
469 groupId, articleId, version);
470
471 String content = GetterUtil.getString(article.getContent());
472
473 if (content.indexOf("\\n") != -1) {
474 content = StringUtil.replace(
475 content,
476 new String[] {"\\n", "\\r"},
477 new String[] {"\n", "\r"});
478
479 article.setContent(content);
480
481 journalArticlePersistence.update(article, false);
482 }
483 }
484
485 public void checkStructure(long groupId, String articleId, double version)
486 throws PortalException, SystemException {
487
488 JournalArticle article = journalArticlePersistence.findByG_A_V(
489 groupId, articleId, version);
490
491 if (Validator.isNull(article.getStructureId())) {
492 return;
493 }
494
495 try {
496 checkStructure(article);
497 }
498 catch (DocumentException de) {
499 _log.error(de, de);
500 }
501 }
502
503 public JournalArticle copyArticle(
504 long userId, long groupId, String oldArticleId, String newArticleId,
505 boolean autoArticleId, double version)
506 throws PortalException, SystemException {
507
508
509
510 User user = userPersistence.findByPrimaryKey(userId);
511 oldArticleId = oldArticleId.trim().toUpperCase();
512 newArticleId = newArticleId.trim().toUpperCase();
513 Date now = new Date();
514
515 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
516 groupId, oldArticleId, version);
517
518 if (autoArticleId) {
519 newArticleId = String.valueOf(counterLocalService.increment());
520 }
521 else {
522 validate(groupId, newArticleId);
523 }
524
525 long id = counterLocalService.increment();
526
527 long resourcePrimKey =
528 journalArticleResourceLocalService.getArticleResourcePrimKey(
529 groupId, newArticleId);
530
531 JournalArticle newArticle = journalArticlePersistence.create(id);
532
533 newArticle.setResourcePrimKey(resourcePrimKey);
534 newArticle.setGroupId(groupId);
535 newArticle.setCompanyId(user.getCompanyId());
536 newArticle.setUserId(user.getUserId());
537 newArticle.setUserName(user.getFullName());
538 newArticle.setCreateDate(now);
539 newArticle.setModifiedDate(now);
540 newArticle.setArticleId(newArticleId);
541 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
542 newArticle.setTitle(oldArticle.getTitle());
543 newArticle.setDescription(oldArticle.getDescription());
544
545 try {
546 copyArticleImages(oldArticle, newArticle);
547 }
548 catch (Exception e) {
549 newArticle.setContent(oldArticle.getContent());
550 }
551
552 newArticle.setType(oldArticle.getType());
553 newArticle.setStructureId(oldArticle.getStructureId());
554 newArticle.setTemplateId(oldArticle.getTemplateId());
555 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
556 newArticle.setDisplayDate(oldArticle.getDisplayDate());
557 newArticle.setExpirationDate(oldArticle.getExpirationDate());
558 newArticle.setReviewDate(oldArticle.getReviewDate());
559 newArticle.setIndexable(oldArticle.isIndexable());
560 newArticle.setSmallImage(oldArticle.isSmallImage());
561 newArticle.setSmallImageId(counterLocalService.increment());
562 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
563 newArticle.setStatus(oldArticle.getStatus());
564
565 journalArticlePersistence.update(newArticle, false);
566
567
568
569 addArticleResources(newArticle, true, true);
570
571
572
573 if (oldArticle.getSmallImage()) {
574 Image image = imageLocalService.getImage(
575 oldArticle.getSmallImageId());
576
577 byte[] smallImageBytes = image.getTextObj();
578
579 imageLocalService.updateImage(
580 newArticle.getSmallImageId(), smallImageBytes);
581 }
582
583
584
585 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
586 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
587 String[] assetTagNames = assetTagLocalService.getTagNames(
588 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
589
590 updateAsset(userId, newArticle, assetCategoryIds, assetTagNames, null);
591
592 return newArticle;
593 }
594
595 public void deleteArticle(
596 JournalArticle article, String articleURL,
597 ServiceContext serviceContext)
598 throws PortalException, SystemException {
599
600 if (article.isApproved() &&
601 isLatestVersion(
602 article.getGroupId(), article.getArticleId(),
603 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
604
605 updatePreviousApprovedArticle(article);
606 }
607
608
609
610 PortletPreferences preferences =
611 ServiceContextUtil.getPortletPreferences(serviceContext);
612
613 if ((preferences != null) && !article.isApproved() &&
614 isLatestVersion(
615 article.getGroupId(), article.getArticleId(),
616 article.getVersion())) {
617
618 sendEmail(
619 article, articleURL, preferences, "denied", serviceContext);
620 }
621
622
623
624 journalArticleImageLocalService.deleteImages(
625 article.getGroupId(), article.getArticleId(), article.getVersion());
626
627
628
629 if (!article.isDraft()) {
630 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
631 article.getCompanyId(), article.getGroupId(),
632 JournalArticle.class.getName(), article.getId());
633 }
634
635 int articlesCount = journalArticlePersistence.countByG_A(
636 article.getGroupId(), article.getArticleId());
637
638 if (articlesCount == 1) {
639
640
641
642 ratingsStatsLocalService.deleteStats(
643 JournalArticle.class.getName(), article.getResourcePrimKey());
644
645
646
647 mbMessageLocalService.deleteDiscussionMessages(
648 JournalArticle.class.getName(), article.getResourcePrimKey());
649
650
651
652 assetEntryLocalService.deleteEntry(
653 JournalArticle.class.getName(), article.getResourcePrimKey());
654
655
656
657 journalContentSearchLocalService.deleteArticleContentSearches(
658 article.getGroupId(), article.getArticleId());
659
660
661
662 imageLocalService.deleteImage(article.getSmallImageId());
663
664
665
666 expandoValueLocalService.deleteValues(
667 JournalArticle.class.getName(), article.getResourcePrimKey());
668
669
670
671 resourceLocalService.deleteResource(
672 article.getCompanyId(), JournalArticle.class.getName(),
673 ResourceConstants.SCOPE_INDIVIDUAL,
674 article.getResourcePrimKey());
675
676
677
678 try {
679 journalArticleResourceLocalService.deleteArticleResource(
680 article.getGroupId(), article.getArticleId());
681 }
682 catch (NoSuchArticleResourceException nsare) {
683 }
684 }
685
686
687
688 journalArticlePersistence.remove(article);
689 }
690
691 public void deleteArticle(
692 long groupId, String articleId, double version, String articleURL,
693 ServiceContext serviceContext)
694 throws PortalException, SystemException {
695
696 JournalArticle article = journalArticlePersistence.findByG_A_V(
697 groupId, articleId, version);
698
699 deleteArticle(article, articleURL, serviceContext);
700 }
701
702 public void deleteArticle(
703 long groupId, String articleId, ServiceContext serviceContext)
704 throws PortalException, SystemException {
705
706 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
707 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
708 new ArticleVersionComparator(true));
709
710 for (JournalArticle article : articles) {
711 deleteArticle(article, null, serviceContext);
712 }
713 }
714
715 public void deleteArticles(long groupId)
716 throws PortalException, SystemException {
717
718 for (JournalArticle article :
719 journalArticlePersistence.findByGroupId(groupId)) {
720
721 deleteArticle(article, null, null);
722 }
723 }
724
725 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
726 throws SystemException {
727
728 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
729 groupId, layoutUuid);
730
731 for (JournalArticle article: articles) {
732 article.setLayoutUuid(StringPool.BLANK);
733
734 journalArticlePersistence.update(article, false);
735 }
736 }
737
738 public JournalArticle expireArticle(
739 long userId, long groupId, String articleId, double version,
740 String articleURL, ServiceContext serviceContext)
741 throws PortalException, SystemException {
742
743 return updateStatus(
744 userId, groupId, articleId, version,
745 WorkflowConstants.STATUS_EXPIRED, articleURL, serviceContext);
746 }
747
748 public void expireArticle(
749 long userId, long groupId, String articleId, String articleURL,
750 ServiceContext serviceContext)
751 throws PortalException, SystemException {
752
753 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
754 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
755 new ArticleVersionComparator(true));
756
757 for (JournalArticle article : articles) {
758 expireArticle(
759 userId, groupId, article.getArticleId(), article.getVersion(),
760 articleURL, serviceContext);
761 }
762 }
763
764 public JournalArticle getArticle(long id)
765 throws PortalException, SystemException {
766
767 return journalArticlePersistence.findByPrimaryKey(id);
768 }
769
770 public JournalArticle getArticle(long groupId, String articleId)
771 throws PortalException, SystemException {
772
773
774
775
776 try {
777 return getLatestArticle(
778 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
779 }
780 catch (NoSuchArticleException nsae) {
781 return getLatestArticle(
782 groupId, articleId, WorkflowConstants.STATUS_ANY);
783 }
784 }
785
786 public JournalArticle getArticle(
787 long groupId, String articleId, double version)
788 throws PortalException, SystemException {
789
790 return journalArticlePersistence.findByG_A_V(
791 groupId, articleId, version);
792 }
793
794 public JournalArticle getArticle(
795 long groupId, String className, long classPK)
796 throws PortalException, SystemException {
797
798 long classNameId = PortalUtil.getClassNameId(className);
799
800 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
801 groupId, classNameId, classPK);
802
803 if (articles.isEmpty()) {
804 throw new NoSuchArticleException(
805 "No approved JournalArticle exists with the key {groupId="
806 + groupId + ", className=" + className + ", classPK=" +
807 classPK + "}");
808 }
809
810 return articles.get(0);
811 }
812
813 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
814 throws PortalException, SystemException {
815
816
817
818
819 try {
820 return getLatestArticleByUrlTitle(
821 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
822 }
823 catch (NoSuchArticleException nsae) {
824 return getLatestArticleByUrlTitle(
825 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
826 }
827 }
828
829 public String getArticleContent(
830 JournalArticle article, String templateId, String viewMode,
831 String languageId, ThemeDisplay themeDisplay)
832 throws PortalException, SystemException {
833
834 JournalArticleDisplay articleDisplay = getArticleDisplay(
835 article, templateId, viewMode, languageId, 1, null, themeDisplay);
836
837 if (articleDisplay == null) {
838 return StringPool.BLANK;
839 }
840 else {
841 return articleDisplay.getContent();
842 }
843 }
844
845 public String getArticleContent(
846 long groupId, String articleId, double version, String viewMode,
847 String templateId, String languageId, ThemeDisplay themeDisplay)
848 throws PortalException, SystemException {
849
850 JournalArticleDisplay articleDisplay = getArticleDisplay(
851 groupId, articleId, version, templateId, viewMode, languageId,
852 themeDisplay);
853
854 if (articleDisplay == null) {
855 return StringPool.BLANK;
856 }
857 else {
858 return articleDisplay.getContent();
859 }
860 }
861
862 public String getArticleContent(
863 long groupId, String articleId, double version, String viewMode,
864 String languageId, ThemeDisplay themeDisplay)
865 throws PortalException, SystemException {
866
867 return getArticleContent(
868 groupId, articleId, version, viewMode, null, languageId,
869 themeDisplay);
870 }
871
872 public String getArticleContent(
873 long groupId, String articleId, String viewMode, String templateId,
874 String languageId, ThemeDisplay themeDisplay)
875 throws PortalException, SystemException {
876
877 JournalArticleDisplay articleDisplay = getArticleDisplay(
878 groupId, articleId, templateId, viewMode, languageId, themeDisplay);
879
880 return articleDisplay.getContent();
881 }
882
883 public String getArticleContent(
884 long groupId, String articleId, String viewMode, String languageId,
885 ThemeDisplay themeDisplay)
886 throws PortalException, SystemException {
887
888 return getArticleContent(
889 groupId, articleId, viewMode, null, languageId, themeDisplay);
890 }
891
892 public JournalArticleDisplay getArticleDisplay(
893 JournalArticle article, String templateId, String viewMode,
894 String languageId, int page, String xmlRequest,
895 ThemeDisplay themeDisplay)
896 throws PortalException, SystemException {
897
898 String content = null;
899
900 if (page < 1) {
901 page = 1;
902 }
903
904 int numberOfPages = 1;
905 boolean paginate = false;
906 boolean pageFlow = false;
907
908 boolean cacheable = true;
909
910 if (Validator.isNull(xmlRequest)) {
911 xmlRequest = "<request />";
912 }
913
914 Map<String, String> tokens = JournalUtil.getTokens(
915 article.getGroupId(), themeDisplay, xmlRequest);
916
917 tokens.put(
918 "article_resource_pk",
919 String.valueOf(article.getResourcePrimKey()));
920
921 String defaultTemplateId = article.getTemplateId();
922
923 if (article.isTemplateDriven()) {
924 if (Validator.isNull(templateId)) {
925 templateId = defaultTemplateId;
926 }
927
928 tokens.put("structure_id", article.getStructureId());
929 tokens.put("template_id", templateId);
930 }
931
932 String xml = article.getContent();
933
934 try {
935 Document document = null;
936
937 Element rootElement = null;
938
939 if (article.isTemplateDriven()) {
940 document = SAXReaderUtil.read(xml);
941
942 rootElement = document.getRootElement();
943
944 Document requestDocument = SAXReaderUtil.read(xmlRequest);
945
946 List<Element> pages = rootElement.elements("page");
947
948 if (!pages.isEmpty()) {
949 pageFlow = true;
950
951 String targetPage = requestDocument.valueOf(
952 "/request/parameters/parameter[name='targetPage']/" +
953 "value");
954
955 Element pageElement = null;
956
957 if (Validator.isNotNull(targetPage)) {
958 XPath xPathSelector = SAXReaderUtil.createXPath(
959 "/root/page[@id = '" + targetPage + "']");
960
961 pageElement = (Element)xPathSelector.selectSingleNode(
962 document);
963 }
964
965 if (pageElement != null) {
966 document = SAXReaderUtil.createDocument(pageElement);
967
968 rootElement = document.getRootElement();
969
970 numberOfPages = pages.size();
971 }
972 else {
973 if (page > pages.size()) {
974 page = 1;
975 }
976
977 pageElement = pages.get(page - 1);
978
979 document = SAXReaderUtil.createDocument(pageElement);
980
981 rootElement = document.getRootElement();
982
983 numberOfPages = pages.size();
984 paginate = true;
985 }
986 }
987
988 rootElement.add(requestDocument.getRootElement().createCopy());
989
990 JournalUtil.addAllReservedEls(
991 rootElement, tokens, article, languageId);
992
993 xml = DDMXMLUtil.formatXML(document);
994 }
995 }
996 catch (DocumentException de) {
997 throw new SystemException(de);
998 }
999 catch (IOException ioe) {
1000 throw new SystemException(ioe);
1001 }
1002
1003 try {
1004 if (_log.isDebugEnabled()) {
1005 _log.debug(
1006 "Transforming " + article.getArticleId() + " " +
1007 article.getVersion() + " " + languageId);
1008 }
1009
1010 String script = null;
1011 String langType = null;
1012
1013 if (article.isTemplateDriven()) {
1014
1015
1016
1017
1018
1019
1020
1021 JournalTemplate template = null;
1022
1023 try {
1024 template = journalTemplatePersistence.findByG_T(
1025 article.getGroupId(), templateId);
1026 }
1027 catch (NoSuchTemplateException nste1) {
1028 try {
1029 Group companyGroup = groupLocalService.getCompanyGroup(
1030 article.getCompanyId());
1031
1032 template = journalTemplatePersistence.findByG_T(
1033 companyGroup.getGroupId(), templateId);
1034
1035 tokens.put(
1036 "company_group_id",
1037 String.valueOf(companyGroup.getGroupId()));
1038 }
1039 catch (NoSuchTemplateException nste2) {
1040 if (!defaultTemplateId.equals(templateId)) {
1041 template = journalTemplatePersistence.findByG_T(
1042 article.getGroupId(), defaultTemplateId);
1043 }
1044 else {
1045 throw nste1;
1046 }
1047 }
1048 }
1049
1050 script = template.getXsl();
1051 langType = template.getLangType();
1052 cacheable = template.isCacheable();
1053 }
1054
1055 content = JournalUtil.transform(
1056 themeDisplay, tokens, viewMode, languageId, xml, script,
1057 langType);
1058
1059 if (!pageFlow) {
1060 String[] pieces = StringUtil.split(
1061 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1062
1063 if (pieces.length > 1) {
1064 if (page > pieces.length) {
1065 page = 1;
1066 }
1067
1068 content = pieces[page - 1];
1069 numberOfPages = pieces.length;
1070 paginate = true;
1071 }
1072 }
1073 }
1074 catch (Exception e) {
1075 throw new SystemException(e);
1076 }
1077
1078 return new JournalArticleDisplayImpl(
1079 article.getCompanyId(), article.getId(),
1080 article.getResourcePrimKey(), article.getGroupId(),
1081 article.getUserId(), article.getArticleId(), article.getVersion(),
1082 article.getTitle(languageId), article.getUrlTitle(),
1083 article.getDescription(languageId), article.getAvailableLocales(),
1084 content, article.getType(), article.getStructureId(), templateId,
1085 article.isSmallImage(), article.getSmallImageId(),
1086 article.getSmallImageURL(), numberOfPages, page, paginate,
1087 cacheable);
1088 }
1089
1090 public JournalArticleDisplay getArticleDisplay(
1091 long groupId, String articleId, double version, String templateId,
1092 String viewMode, String languageId, int page, String xmlRequest,
1093 ThemeDisplay themeDisplay)
1094 throws PortalException, SystemException {
1095
1096 Date now = new Date();
1097
1098 JournalArticle article = journalArticlePersistence.findByG_A_V(
1099 groupId, articleId, version);
1100
1101 if (article.isExpired()) {
1102 Date expirationDate = article.getExpirationDate();
1103
1104 if ((expirationDate != null) && expirationDate.before(now)) {
1105 return null;
1106 }
1107 }
1108
1109 if (article.getDisplayDate().after(now)) {
1110 return null;
1111 }
1112
1113 return getArticleDisplay(
1114 article, templateId, viewMode, languageId, page, xmlRequest,
1115 themeDisplay);
1116 }
1117
1118 public JournalArticleDisplay getArticleDisplay(
1119 long groupId, String articleId, double version, String templateId,
1120 String viewMode, String languageId, ThemeDisplay themeDisplay)
1121 throws PortalException, SystemException {
1122
1123 return getArticleDisplay(
1124 groupId, articleId, version, templateId, viewMode, languageId, 1,
1125 null, themeDisplay);
1126 }
1127
1128 public JournalArticleDisplay getArticleDisplay(
1129 long groupId, String articleId, String viewMode, String languageId,
1130 int page, String xmlRequest, ThemeDisplay themeDisplay)
1131 throws PortalException, SystemException {
1132
1133 return getArticleDisplay(
1134 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
1135 themeDisplay);
1136 }
1137
1138 public JournalArticleDisplay getArticleDisplay(
1139 long groupId, String articleId, String templateId, String viewMode,
1140 String languageId, int page, String xmlRequest,
1141 ThemeDisplay themeDisplay)
1142 throws PortalException, SystemException {
1143
1144 JournalArticle article = getDisplayArticle(groupId, articleId);
1145
1146 return getArticleDisplay(
1147 groupId, articleId, article.getVersion(), templateId, viewMode,
1148 languageId, page, xmlRequest, themeDisplay);
1149 }
1150
1151 public JournalArticleDisplay getArticleDisplay(
1152 long groupId, String articleId, String templateId, String viewMode,
1153 String languageId, ThemeDisplay themeDisplay)
1154 throws PortalException, SystemException {
1155
1156 JournalArticle article = getDisplayArticle(groupId, articleId);
1157
1158 return getArticleDisplay(
1159 groupId, articleId, article.getVersion(), templateId, viewMode,
1160 languageId, themeDisplay);
1161 }
1162
1163 public JournalArticleDisplay getArticleDisplay(
1164 long groupId, String articleId, String viewMode, String languageId,
1165 ThemeDisplay themeDisplay)
1166 throws PortalException, SystemException {
1167
1168 return getArticleDisplay(
1169 groupId, articleId, null, viewMode, languageId, themeDisplay);
1170 }
1171
1172 public List<JournalArticle> getArticles() throws SystemException {
1173 return journalArticlePersistence.findAll();
1174 }
1175
1176 public List<JournalArticle> getArticles(long groupId)
1177 throws SystemException {
1178
1179 return journalArticlePersistence.findByGroupId(groupId);
1180 }
1181
1182 public List<JournalArticle> getArticles(long groupId, int start, int end)
1183 throws SystemException {
1184
1185 return journalArticlePersistence.findByGroupId(groupId, start, end);
1186 }
1187
1188 public List<JournalArticle> getArticles(
1189 long groupId, int start, int end, OrderByComparator obc)
1190 throws SystemException {
1191
1192 return journalArticlePersistence.findByGroupId(
1193 groupId, start, end, obc);
1194 }
1195
1196 public List<JournalArticle> getArticles(long groupId, String articleId)
1197 throws SystemException {
1198
1199 return journalArticlePersistence.findByG_A(groupId, articleId);
1200 }
1201
1202 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
1203 throws SystemException {
1204
1205 return journalArticlePersistence.findBySmallImageId(smallImageId);
1206 }
1207
1208 public int getArticlesCount(long groupId) throws SystemException {
1209 return journalArticlePersistence.countByGroupId(groupId);
1210 }
1211
1212 public List<JournalArticle> getCompanyArticles(
1213 long companyId, double version, int status, int start, int end)
1214 throws SystemException {
1215
1216 if (status == WorkflowConstants.STATUS_ANY) {
1217 return journalArticlePersistence.findByC_V(
1218 companyId, version, start, end, new ArticleIDComparator(true));
1219 }
1220 else {
1221 return journalArticlePersistence.findByC_V_ST(
1222 companyId, version, status, start, end,
1223 new ArticleIDComparator(true));
1224 }
1225 }
1226
1227 public List<JournalArticle> getCompanyArticles(
1228 long companyId, int status, int start, int end)
1229 throws SystemException {
1230
1231 if (status == WorkflowConstants.STATUS_ANY) {
1232 return journalArticlePersistence.findByCompanyId(
1233 companyId, start, end, new ArticleIDComparator(true));
1234 }
1235 else {
1236 return journalArticlePersistence.findByC_ST(
1237 companyId, status, start, end, new ArticleIDComparator(true));
1238 }
1239 }
1240
1241 public int getCompanyArticlesCount(
1242 long companyId, double version, int status, int start, int end)
1243 throws SystemException {
1244
1245 if (status == WorkflowConstants.STATUS_ANY) {
1246 return journalArticlePersistence.countByC_V(companyId, version);
1247 }
1248 else {
1249 return journalArticlePersistence.countByC_V_ST(
1250 companyId, version, status);
1251 }
1252 }
1253
1254 public int getCompanyArticlesCount(long companyId, int status)
1255 throws SystemException {
1256
1257 if (status == WorkflowConstants.STATUS_ANY) {
1258 return journalArticlePersistence.countByCompanyId(companyId);
1259 }
1260 else {
1261 return journalArticlePersistence.countByC_ST(companyId, status);
1262 }
1263 }
1264
1265 public JournalArticle getDisplayArticle(long groupId, String articleId)
1266 throws PortalException, SystemException {
1267
1268 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
1269 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1270
1271 if (articles.isEmpty()) {
1272 throw new NoSuchArticleException(
1273 "No approved JournalArticle exists with the key {groupId=" +
1274 groupId + ", " + "articleId=" + articleId + "}");
1275
1276 }
1277
1278 Date now = new Date();
1279
1280 for (int i = 0; i < articles.size(); i++) {
1281 JournalArticle article = articles.get(i);
1282
1283 Date expirationDate = article.getExpirationDate();
1284
1285 if (article.getDisplayDate().before(now) &&
1286 ((expirationDate == null) || expirationDate.after(now))) {
1287
1288 return article;
1289 }
1290 }
1291
1292 return articles.get(0);
1293 }
1294
1295 public JournalArticle getDisplayArticleByUrlTitle(
1296 long groupId, String urlTitle)
1297 throws PortalException, SystemException {
1298
1299 List<JournalArticle> articles = null;
1300
1301 OrderByComparator orderByComparator = new ArticleVersionComparator();
1302
1303 articles = journalArticlePersistence.findByG_UT_ST(
1304 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
1305 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
1306
1307 if (articles.isEmpty()) {
1308 throw new NoSuchArticleException(
1309 "No JournalArticle exists with the key {groupId=" + groupId +
1310 ", urlTitle=" + urlTitle + "}");
1311 }
1312
1313 Date now = new Date();
1314
1315 for (JournalArticle article : articles) {
1316 Date expirationDate = article.getExpirationDate();
1317
1318 if (article.getDisplayDate().before(now) &&
1319 ((expirationDate == null) || expirationDate.after(now))) {
1320
1321 return article;
1322 }
1323 }
1324
1325 return articles.get(0);
1326 }
1327
1328 public JournalArticle getLatestArticle(long resourcePrimKey)
1329 throws PortalException, SystemException {
1330
1331 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
1332 }
1333
1334 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
1335 throws PortalException, SystemException {
1336
1337 return getLatestArticle(resourcePrimKey, status, true);
1338 }
1339
1340 public JournalArticle getLatestArticle(
1341 long resourcePrimKey, int status, boolean preferApproved)
1342 throws PortalException, SystemException {
1343
1344 List<JournalArticle> articles = null;
1345
1346 OrderByComparator orderByComparator = new ArticleVersionComparator();
1347
1348 if (status == WorkflowConstants.STATUS_ANY) {
1349 if (preferApproved) {
1350 articles = journalArticlePersistence.findByR_ST(
1351 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
1352 orderByComparator);
1353 }
1354
1355 if ((articles == null) || (articles.size() == 0)) {
1356 articles = journalArticlePersistence.findByResourcePrimKey(
1357 resourcePrimKey, 0, 1, orderByComparator);
1358 }
1359 }
1360 else {
1361 articles = journalArticlePersistence.findByR_ST(
1362 resourcePrimKey, status, 0, 1, orderByComparator);
1363 }
1364
1365 if (articles.isEmpty()) {
1366 throw new NoSuchArticleException(
1367 "No JournalArticle exists with the key {resourcePrimKey=" +
1368 resourcePrimKey + "}");
1369 }
1370
1371 return articles.get(0);
1372 }
1373
1374 public JournalArticle getLatestArticle(long groupId, String articleId)
1375 throws PortalException, SystemException {
1376
1377 return getLatestArticle(
1378 groupId, articleId, WorkflowConstants.STATUS_ANY);
1379 }
1380
1381 public JournalArticle getLatestArticle(
1382 long groupId, String articleId, int status)
1383 throws PortalException, SystemException {
1384
1385 List<JournalArticle> articles = null;
1386
1387 OrderByComparator orderByComparator = new ArticleVersionComparator();
1388
1389 if (status == WorkflowConstants.STATUS_ANY) {
1390 articles = journalArticlePersistence.findByG_A(
1391 groupId, articleId, 0, 1, orderByComparator);
1392 }
1393 else {
1394 articles = journalArticlePersistence.findByG_A_ST(
1395 groupId, articleId, status, 0, 1, orderByComparator);
1396 }
1397
1398 if (articles.isEmpty()) {
1399 throw new NoSuchArticleException(
1400 "No JournalArticle exists with the key {groupId=" + groupId +
1401 ", articleId=" + articleId + ", status=" + status + "}");
1402 }
1403
1404 return articles.get(0);
1405 }
1406
1407 public JournalArticle getLatestArticle(
1408 long groupId, String className, long classPK)
1409 throws PortalException, SystemException {
1410
1411 long classNameId = PortalUtil.getClassNameId(className);
1412
1413 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1414 groupId, classNameId, classPK, 0, 1,
1415 new ArticleVersionComparator());
1416
1417 if (articles.isEmpty()) {
1418 throw new NoSuchArticleException(
1419 "No JournalArticle exists with the key {groupId=" + groupId +
1420 ", className=" + className + ", classPK =" + classPK + "}");
1421 }
1422
1423 return articles.get(0);
1424 }
1425
1426 public JournalArticle getLatestArticleByUrlTitle(
1427 long groupId, String urlTitle, int status)
1428 throws PortalException, SystemException {
1429
1430 List<JournalArticle> articles = null;
1431
1432 OrderByComparator orderByComparator = new ArticleVersionComparator();
1433
1434 if (status == WorkflowConstants.STATUS_ANY) {
1435 articles = journalArticlePersistence.findByG_UT(
1436 groupId, urlTitle, 0, 1, orderByComparator);
1437 }
1438 else {
1439 articles = journalArticlePersistence.findByG_UT_ST(
1440 groupId, urlTitle, status, 0, 1, orderByComparator);
1441 }
1442
1443 if (articles.isEmpty()) {
1444 throw new NoSuchArticleException(
1445 "No JournalArticle exists with the key {groupId=" + groupId +
1446 ", urlTitle=" + urlTitle + ", status=" + status + "}");
1447 }
1448
1449 return articles.get(0);
1450 }
1451
1452 public double getLatestVersion(long groupId, String articleId)
1453 throws PortalException, SystemException {
1454
1455 JournalArticle article = getLatestArticle(groupId, articleId);
1456
1457 return article.getVersion();
1458 }
1459
1460 public double getLatestVersion(long groupId, String articleId, int status)
1461 throws PortalException, SystemException {
1462
1463 JournalArticle article = getLatestArticle(groupId, articleId, status);
1464
1465 return article.getVersion();
1466 }
1467
1468 public List<JournalArticle> getStructureArticles(
1469 long groupId, String structureId)
1470 throws SystemException {
1471
1472 return journalArticlePersistence.findByG_S(groupId, structureId);
1473 }
1474
1475 public List<JournalArticle> getStructureArticles(
1476 long groupId, String structureId, int start, int end,
1477 OrderByComparator obc)
1478 throws SystemException {
1479
1480 return journalArticlePersistence.findByG_S(
1481 groupId, structureId, start, end, obc);
1482 }
1483
1484 public int getStructureArticlesCount(long groupId, String structureId)
1485 throws SystemException {
1486
1487 return journalArticlePersistence.countByG_S(groupId, structureId);
1488 }
1489
1490 public List<JournalArticle> getTemplateArticles(
1491 long groupId, String templateId)
1492 throws SystemException {
1493
1494 return journalArticlePersistence.findByG_T(groupId, templateId);
1495 }
1496
1497 public List<JournalArticle> getTemplateArticles(
1498 long groupId, String templateId, int start, int end,
1499 OrderByComparator obc)
1500 throws SystemException {
1501
1502 return journalArticlePersistence.findByG_T(
1503 groupId, templateId, start, end, obc);
1504 }
1505
1506 public int getTemplateArticlesCount(long groupId, String templateId)
1507 throws SystemException {
1508
1509 return journalArticlePersistence.countByG_T(groupId, templateId);
1510 }
1511
1512 public boolean hasArticle(long groupId, String articleId)
1513 throws SystemException {
1514
1515 try {
1516 getArticle(groupId, articleId);
1517
1518 return true;
1519 }
1520 catch (PortalException pe) {
1521 return false;
1522 }
1523 }
1524
1525 public boolean isLatestVersion(
1526 long groupId, String articleId, double version)
1527 throws PortalException, SystemException {
1528
1529 if (getLatestVersion(groupId, articleId) == version) {
1530 return true;
1531 }
1532 else {
1533 return false;
1534 }
1535 }
1536
1537 public boolean isLatestVersion(
1538 long groupId, String articleId, double version, int status)
1539 throws PortalException, SystemException {
1540
1541 if (getLatestVersion(groupId, articleId, status) == version) {
1542 return true;
1543 }
1544 else {
1545 return false;
1546 }
1547 }
1548
1549 public JournalArticle removeArticleLocale(
1550 long groupId, String articleId, double version, String languageId)
1551 throws PortalException, SystemException {
1552
1553 JournalArticle article = journalArticlePersistence.findByG_A_V(
1554 groupId, articleId, version);
1555
1556 String title = article.getTitle();
1557
1558 title = LocalizationUtil.removeLocalization(
1559 title, "static-content", languageId, true);
1560
1561 article.setTitle(title);
1562
1563 String description = article.getDescription();
1564
1565 description = LocalizationUtil.removeLocalization(
1566 description, "static-content", languageId, true);
1567
1568 article.setDescription(description);
1569
1570 String content = article.getContent();
1571
1572 if (article.isTemplateDriven()) {
1573 content = JournalUtil.removeArticleLocale(content, languageId);
1574 }
1575 else {
1576 content = LocalizationUtil.removeLocalization(
1577 content, "static-content", languageId, true);
1578 }
1579
1580 article.setContent(content);
1581
1582 journalArticlePersistence.update(article, false);
1583
1584 return article;
1585 }
1586
1587 public List<JournalArticle> search(
1588 long companyId, long groupId, long classNameId, String keywords,
1589 Double version, String type, String structureId, String templateId,
1590 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1591 int start, int end, OrderByComparator obc)
1592 throws SystemException {
1593
1594 return journalArticleFinder.findByKeywords(
1595 companyId, groupId, classNameId, keywords, version, type,
1596 structureId, templateId, displayDateGT, displayDateLT, status,
1597 reviewDate, start, end, obc);
1598 }
1599
1600 public List<JournalArticle> search(
1601 long companyId, long groupId, long classNameId, String articleId,
1602 Double version, String title, String description, String content,
1603 String type, String structureId, String templateId,
1604 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1605 boolean andOperator, int start, int end, OrderByComparator obc)
1606 throws SystemException {
1607
1608 return journalArticleFinder.findByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1609 companyId, groupId, classNameId, articleId, version, title,
1610 description, content, type, structureId, templateId, displayDateGT,
1611 displayDateLT, status, reviewDate, andOperator, start, end, obc);
1612 }
1613
1614 public List<JournalArticle> search(
1615 long companyId, long groupId, long classNameId, String articleId,
1616 Double version, String title, String description, String content,
1617 String type, String[] structureIds, String[] templateIds,
1618 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1619 boolean andOperator, int start, int end, OrderByComparator obc)
1620 throws SystemException {
1621
1622 return journalArticleFinder.findByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1623 companyId, groupId, classNameId, articleId, version, title,
1624 description, content, type, structureIds, templateIds,
1625 displayDateGT, displayDateLT, status, reviewDate, andOperator,
1626 start, end, obc);
1627 }
1628
1629 public Hits search(
1630 long companyId, long groupId, long classNameId, String structureId,
1631 String templateId, String keywords,
1632 LinkedHashMap<String, Object> params, int start, int end, Sort sort)
1633 throws SystemException {
1634
1635 String articleId = null;
1636 String title = null;
1637 String description = null;
1638 String content = null;
1639 boolean andOperator = false;
1640
1641 if (Validator.isNotNull(keywords)) {
1642 articleId = keywords;
1643 title = keywords;
1644 description = keywords;
1645 content = keywords;
1646 }
1647 else {
1648 andOperator = true;
1649 }
1650
1651 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
1652
1653 params.put("keywords", keywords);
1654
1655 return search(
1656 companyId, groupId, classNameId, articleId, title, description,
1657 content, null, status, structureId, templateId, params, andOperator,
1658 start, end, sort);
1659 }
1660
1661 public Hits search(
1662 long companyId, long groupId, long classNameId, String articleId,
1663 String title, String description, String content, String type,
1664 String status, String structureId, String templateId,
1665 LinkedHashMap<String, Object> params, boolean andSearch, int start,
1666 int end, Sort sort)
1667 throws SystemException {
1668
1669 try {
1670 Map<String, Serializable> attributes =
1671 new HashMap<String, Serializable>();
1672
1673 attributes.put(Field.CLASS_NAME_ID, classNameId);
1674 attributes.put(Field.CONTENT, content);
1675 attributes.put(Field.DESCRIPTION, description);
1676 attributes.put(Field.STATUS, status);
1677 attributes.put(Field.TITLE, title);
1678 attributes.put(Field.TYPE, type);
1679 attributes.put("articleId", articleId);
1680 attributes.put("params", params);
1681 attributes.put("structureId", structureId);
1682 attributes.put("templateId", templateId);
1683
1684 SearchContext searchContext = new SearchContext();
1685
1686 searchContext.setAndSearch(andSearch);
1687 searchContext.setAttributes(attributes);
1688 searchContext.setCompanyId(companyId);
1689 searchContext.setGroupIds(new long[] {groupId});
1690 searchContext.setEnd(end);
1691
1692 String keywords = (String)params.remove("keywords");
1693
1694 if (Validator.isNotNull(keywords)) {
1695 searchContext.setKeywords(keywords);
1696 }
1697
1698 searchContext.setSorts(new Sort[] {sort});
1699
1700 QueryConfig queryConfig = new QueryConfig();
1701
1702 queryConfig.setHighlightEnabled(false);
1703 queryConfig.setScoreEnabled(false);
1704
1705 searchContext.setQueryConfig(queryConfig);
1706
1707 searchContext.setStart(start);
1708
1709 Indexer indexer = IndexerRegistryUtil.getIndexer(
1710 JournalArticle.class);
1711
1712 return indexer.search(searchContext);
1713 }
1714 catch (Exception e) {
1715 throw new SystemException(e);
1716 }
1717 }
1718
1719 public int searchCount(
1720 long companyId, long groupId, long classNameId, String keywords,
1721 Double version, String type, String structureId, String templateId,
1722 Date displayDateGT, Date displayDateLT, int status, Date reviewDate)
1723 throws SystemException {
1724
1725 return journalArticleFinder.countByKeywords(
1726 companyId, groupId, classNameId, keywords, version, type,
1727 structureId, templateId, displayDateGT, displayDateLT, status,
1728 reviewDate);
1729 }
1730
1731 public int searchCount(
1732 long companyId, long groupId, long classNameId, String articleId,
1733 Double version, String title, String description, String content,
1734 String type, String structureId, String templateId,
1735 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1736 boolean andOperator)
1737 throws SystemException {
1738
1739 return journalArticleFinder.countByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1740 companyId, groupId, classNameId, articleId, version, title,
1741 description, content, type, structureId, templateId, displayDateGT,
1742 displayDateLT, status, reviewDate, andOperator);
1743 }
1744
1745 public int searchCount(
1746 long companyId, long groupId, long classNameId, String articleId,
1747 Double version, String title, String description, String content,
1748 String type, String[] structureIds, String[] templateIds,
1749 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1750 boolean andOperator)
1751 throws SystemException {
1752
1753 return journalArticleFinder.countByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1754 companyId, groupId, classNameId, articleId, version, title,
1755 description, content, type, structureIds, templateIds,
1756 displayDateGT, displayDateLT, status, reviewDate, andOperator);
1757 }
1758
1759 public void subscribe(long userId, long groupId)
1760 throws PortalException, SystemException {
1761
1762 subscriptionLocalService.addSubscription(
1763 userId, groupId, JournalArticle.class.getName(), groupId);
1764 }
1765
1766 public void unsubscribe(long userId, long groupId)
1767 throws PortalException, SystemException {
1768
1769 subscriptionLocalService.deleteSubscription(
1770 userId, JournalArticle.class.getName(), groupId);
1771 }
1772
1773 public JournalArticle updateArticle(
1774 long userId, long groupId, String articleId, double version,
1775 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
1776 String content, String layoutUuid, ServiceContext serviceContext)
1777 throws PortalException, SystemException {
1778
1779 User user = userPersistence.findByPrimaryKey(userId);
1780
1781 JournalArticle article = journalArticlePersistence.findByG_A_V(
1782 groupId, articleId, version);
1783
1784 Date displayDate = article.getDisplayDate();
1785
1786 int displayDateMonth = 0;
1787 int displayDateDay = 0;
1788 int displayDateYear = 0;
1789 int displayDateHour = 0;
1790 int displayDateMinute = 0;
1791
1792 if (displayDate != null) {
1793 Calendar displayCal = CalendarFactoryUtil.getCalendar(
1794 user.getTimeZone());
1795
1796 displayCal.setTime(displayDate);
1797
1798 displayDateMonth = displayCal.get(Calendar.MONTH);
1799 displayDateDay = displayCal.get(Calendar.DATE);
1800 displayDateYear = displayCal.get(Calendar.YEAR);
1801 displayDateHour = displayCal.get(Calendar.HOUR);
1802 displayDateMinute = displayCal.get(Calendar.MINUTE);
1803
1804 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
1805 displayDateHour += 12;
1806 }
1807 }
1808
1809 Date expirationDate = article.getExpirationDate();
1810
1811 int expirationDateMonth = 0;
1812 int expirationDateDay = 0;
1813 int expirationDateYear = 0;
1814 int expirationDateHour = 0;
1815 int expirationDateMinute = 0;
1816 boolean neverExpire = true;
1817
1818 if (expirationDate != null) {
1819 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
1820 user.getTimeZone());
1821
1822 expirationCal.setTime(expirationDate);
1823
1824 expirationDateMonth = expirationCal.get(Calendar.MONTH);
1825 expirationDateDay = expirationCal.get(Calendar.DATE);
1826 expirationDateYear = expirationCal.get(Calendar.YEAR);
1827 expirationDateHour = expirationCal.get(Calendar.HOUR);
1828 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
1829 neverExpire = false;
1830
1831 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
1832 expirationDateHour += 12;
1833 }
1834 }
1835
1836 Date reviewDate = article.getReviewDate();
1837
1838 int reviewDateMonth = 0;
1839 int reviewDateDay = 0;
1840 int reviewDateYear = 0;
1841 int reviewDateHour = 0;
1842 int reviewDateMinute = 0;
1843 boolean neverReview = true;
1844
1845 if (reviewDate != null) {
1846 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
1847 user.getTimeZone());
1848
1849 reviewCal.setTime(reviewDate);
1850
1851 reviewDateMonth = reviewCal.get(Calendar.MONTH);
1852 reviewDateDay = reviewCal.get(Calendar.DATE);
1853 reviewDateYear = reviewCal.get(Calendar.YEAR);
1854 reviewDateHour = reviewCal.get(Calendar.HOUR);
1855 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
1856 neverReview = false;
1857
1858 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
1859 reviewDateHour += 12;
1860 }
1861 }
1862
1863 return updateArticle(
1864 userId, groupId, articleId, version, titleMap, descriptionMap,
1865 content, article.getType(), article.getStructureId(),
1866 article.getTemplateId(), layoutUuid, displayDateMonth,
1867 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
1868 expirationDateMonth, expirationDateDay, expirationDateYear,
1869 expirationDateHour, expirationDateMinute, neverExpire,
1870 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
1871 reviewDateMinute, neverReview, article.getIndexable(),
1872 article.isSmallImage(), article.getSmallImageURL(), null, null,
1873 null, serviceContext);
1874 }
1875
1876 public JournalArticle updateArticle(
1877 long userId, long groupId, String articleId, double version,
1878 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
1879 String content, String type, String structureId, String templateId,
1880 String layoutUuid, int displayDateMonth, int displayDateDay,
1881 int displayDateYear, int displayDateHour, int displayDateMinute,
1882 int expirationDateMonth, int expirationDateDay,
1883 int expirationDateYear, int expirationDateHour,
1884 int expirationDateMinute, boolean neverExpire, int reviewDateMonth,
1885 int reviewDateDay, int reviewDateYear, int reviewDateHour,
1886 int reviewDateMinute, boolean neverReview, boolean indexable,
1887 boolean smallImage, String smallImageURL, File smallImageFile,
1888 Map<String, byte[]> images, String articleURL,
1889 ServiceContext serviceContext)
1890 throws PortalException, SystemException {
1891
1892
1893
1894 User user = userPersistence.findByPrimaryKey(userId);
1895 articleId = articleId.trim().toUpperCase();
1896
1897 Date displayDate = PortalUtil.getDate(
1898 displayDateMonth, displayDateDay, displayDateYear,
1899 displayDateHour, displayDateMinute, user.getTimeZone(),
1900 new ArticleDisplayDateException());
1901
1902 Date expirationDate = null;
1903
1904 if (!neverExpire) {
1905 expirationDate = PortalUtil.getDate(
1906 expirationDateMonth, expirationDateDay, expirationDateYear,
1907 expirationDateHour, expirationDateMinute, user.getTimeZone(),
1908 new ArticleExpirationDateException());
1909 }
1910
1911 Date now = new Date();
1912
1913 boolean expired = false;
1914
1915 if ((expirationDate != null) && expirationDate.before(now)) {
1916 expired = true;
1917 }
1918
1919 Date reviewDate = null;
1920
1921 if (!neverReview) {
1922 reviewDate = PortalUtil.getDate(
1923 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
1924 reviewDateMinute, user.getTimeZone(),
1925 new ArticleReviewDateException());
1926 }
1927
1928 byte[] smallImageBytes = null;
1929
1930 try {
1931 smallImageBytes = FileUtil.getBytes(smallImageFile);
1932 }
1933 catch (IOException ioe) {
1934 }
1935
1936 JournalArticle oldArticle = null;
1937 double oldVersion = 0;
1938
1939 boolean incrementVersion = false;
1940
1941 boolean imported = GetterUtil.getBoolean(
1942 serviceContext.getAttribute("imported"));
1943
1944 if (imported) {
1945 oldArticle = getArticle(groupId, articleId, version);
1946 oldVersion = version;
1947
1948 if (!expired) {
1949 incrementVersion = true;
1950 }
1951 else {
1952 return expireArticle(
1953 userId, groupId, articleId, version, articleURL,
1954 serviceContext);
1955 }
1956 }
1957 else {
1958 oldArticle = getLatestArticle(
1959 groupId, articleId, WorkflowConstants.STATUS_ANY);
1960
1961 oldVersion = oldArticle.getVersion();
1962
1963 if ((version > 0) && (version != oldVersion)) {
1964 throw new ArticleVersionException();
1965 }
1966
1967 if (oldArticle.isApproved() || oldArticle.isExpired()) {
1968 incrementVersion = true;
1969 }
1970 }
1971
1972 validate(
1973 user.getCompanyId(), groupId, oldArticle.getClassNameId(), titleMap,
1974 content, type, structureId, templateId, smallImage, smallImageURL,
1975 smallImageFile, smallImageBytes);
1976
1977 JournalArticle article = null;
1978
1979 if (incrementVersion) {
1980 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
1981
1982 long id = counterLocalService.increment();
1983
1984 article = journalArticlePersistence.create(id);
1985
1986 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
1987 article.setGroupId(oldArticle.getGroupId());
1988 article.setCompanyId(oldArticle.getCompanyId());
1989 article.setUserId(user.getUserId());
1990 article.setUserName(user.getFullName());
1991 article.setCreateDate(serviceContext.getModifiedDate(now));
1992 article.setClassNameId(oldArticle.getClassNameId());
1993 article.setClassPK(oldArticle.getClassPK());
1994 article.setArticleId(articleId);
1995 article.setVersion(newVersion);
1996 article.setSmallImageId(oldArticle.getSmallImageId());
1997 }
1998 else {
1999 article = oldArticle;
2000 }
2001
2002 Locale locale = LocaleUtil.getDefault();
2003
2004 String defaultLanguageId = GetterUtil.getString(
2005 serviceContext.getAttribute("defaultLanguageId"));
2006
2007 if (Validator.isNotNull(defaultLanguageId)) {
2008 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
2009 }
2010
2011 String title = titleMap.get(locale);
2012
2013 content = format(
2014 user, groupId, articleId, article.getVersion(), incrementVersion,
2015 content, structureId, images);
2016
2017 article.setModifiedDate(serviceContext.getModifiedDate(now));
2018 article.setTitleMap(titleMap, locale);
2019 article.setUrlTitle(
2020 getUniqueUrlTitle(article.getId(), groupId, articleId, title));
2021 article.setDescriptionMap(descriptionMap, locale);
2022 article.setContent(content);
2023 article.setType(type);
2024 article.setStructureId(structureId);
2025 article.setTemplateId(templateId);
2026 article.setLayoutUuid(layoutUuid);
2027 article.setDisplayDate(displayDate);
2028 article.setExpirationDate(expirationDate);
2029 article.setReviewDate(reviewDate);
2030 article.setIndexable(indexable);
2031 article.setSmallImage(smallImage);
2032
2033 if (article.getSmallImageId() == 0) {
2034 article.setSmallImageId(counterLocalService.increment());
2035 }
2036
2037 article.setSmallImageURL(smallImageURL);
2038
2039 if (oldArticle.isPending()) {
2040 article.setStatus(oldArticle.getStatus());
2041 }
2042 else if (!expired) {
2043 article.setStatus(WorkflowConstants.STATUS_DRAFT);
2044 }
2045 else {
2046 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
2047 }
2048
2049 journalArticlePersistence.update(article, false);
2050
2051
2052
2053 updateAsset(
2054 userId, article, serviceContext.getAssetCategoryIds(),
2055 serviceContext.getAssetTagNames(),
2056 serviceContext.getAssetLinkEntryIds());
2057
2058
2059
2060 ExpandoBridge expandoBridge = article.getExpandoBridge();
2061
2062 expandoBridge.setAttributes(serviceContext);
2063
2064
2065
2066 saveImages(
2067 smallImage, article.getSmallImageId(), smallImageFile,
2068 smallImageBytes);
2069
2070
2071
2072 PortletPreferences preferences =
2073 ServiceContextUtil.getPortletPreferences(serviceContext);
2074
2075
2076
2077 if (serviceContext.getWorkflowAction() ==
2078 WorkflowConstants.ACTION_PUBLISH) {
2079
2080 sendEmail(
2081 article, articleURL, preferences, "requested", serviceContext);
2082
2083 WorkflowHandlerRegistryUtil.startWorkflowInstance(
2084 user.getCompanyId(), groupId, userId,
2085 JournalArticle.class.getName(), article.getId(),
2086 article, serviceContext);
2087 }
2088 else if (article.getVersion() ==
2089 JournalArticleConstants.VERSION_DEFAULT) {
2090
2091
2092
2093 Indexer indexer = IndexerRegistryUtil.getIndexer(
2094 JournalArticle.class);
2095
2096 indexer.reindex(article);
2097 }
2098
2099 return article;
2100 }
2101
2102 public JournalArticle updateArticle(
2103 long userId, long groupId, String articleId, double version,
2104 String content, ServiceContext serviceContext)
2105 throws PortalException, SystemException {
2106
2107 JournalArticle article = journalArticlePersistence.findByG_A_V(
2108 groupId, articleId, version);
2109
2110 return updateArticle(
2111 userId, groupId, articleId, version, article.getTitleMap(),
2112 article.getDescriptionMap(), content, article.getLayoutUuid(),
2113 serviceContext);
2114 }
2115
2116 public JournalArticle updateArticleTranslation(
2117 long groupId, String articleId, double version, Locale locale,
2118 String title, String description, String content,
2119 Map<String, byte[]> images)
2120 throws PortalException, SystemException {
2121
2122 validateContent(content);
2123
2124 JournalArticle oldArticle = getLatestArticle(
2125 groupId, articleId, WorkflowConstants.STATUS_ANY);
2126
2127 double oldVersion = oldArticle.getVersion();
2128
2129 if ((version > 0) && (version != oldVersion)) {
2130 throw new ArticleVersionException();
2131 }
2132
2133 JournalArticle article = null;
2134
2135 User user = userService.getUserById(oldArticle.getUserId());
2136
2137 if (!oldArticle.isDraft()) {
2138 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
2139
2140 long id = counterLocalService.increment();
2141
2142 article = journalArticlePersistence.create(id);
2143
2144 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
2145 article.setGroupId(oldArticle.getGroupId());
2146 article.setCompanyId(oldArticle.getCompanyId());
2147 article.setUserId(oldArticle.getUserId());
2148 article.setUserName(user.getFullName());
2149 article.setCreateDate(new Date());
2150 article.setModifiedDate(new Date());
2151 article.setClassNameId(oldArticle.getClassNameId());
2152 article.setClassPK(oldArticle.getClassPK());
2153 article.setArticleId(articleId);
2154 article.setVersion(newVersion);
2155 article.setTitleMap(oldArticle.getTitleMap());
2156 article.setUrlTitle(
2157 getUniqueUrlTitle(article.getId(), groupId, articleId, title));
2158 article.setDescriptionMap(oldArticle.getDescriptionMap());
2159 article.setType(oldArticle.getType());
2160 article.setStructureId(oldArticle.getStructureId());
2161 article.setTemplateId(oldArticle.getTemplateId());
2162 article.setLayoutUuid(oldArticle.getLayoutUuid());
2163 article.setDisplayDate(oldArticle.getDisplayDate());
2164 article.setExpirationDate(oldArticle.getExpirationDate());
2165 article.setReviewDate(oldArticle.getReviewDate());
2166 article.setIndexable(oldArticle.getIndexable());
2167 article.setSmallImage(oldArticle.getSmallImage());
2168 article.setSmallImageId(oldArticle.getSmallImageId());
2169
2170 if (article.getSmallImageId() == 0) {
2171 article.setSmallImageId(counterLocalService.increment());
2172 }
2173
2174 article.setSmallImageURL(oldArticle.getSmallImageURL());
2175
2176 article.setStatus(WorkflowConstants.STATUS_DRAFT);
2177 article.setStatusDate(new Date());
2178 }
2179 else {
2180 article = oldArticle;
2181 }
2182
2183 Map<Locale, String> titleMap = article.getTitleMap();
2184
2185 titleMap.put(locale, title);
2186
2187 article.setTitleMap(titleMap);
2188
2189 Map<Locale, String> descriptionMap = article.getDescriptionMap();
2190
2191 descriptionMap.put(locale, description);
2192
2193 article.setDescriptionMap(descriptionMap);
2194
2195 content = format(
2196 user, groupId, articleId, version, !oldArticle.isDraft(), content,
2197 oldArticle.getStructureId(), images);
2198
2199 article.setContent(content);
2200
2201 journalArticlePersistence.update(article, false);
2202
2203 return article;
2204 }
2205
2206 public void updateAsset(
2207 long userId, JournalArticle article, long[] assetCategoryIds,
2208 String[] assetTagNames, long[] assetLinkEntryIds)
2209 throws PortalException, SystemException {
2210
2211
2212
2213
2214 Date[] dateInterval = getDateInterval(
2215 article.getGroupId(), article.getArticleId(),
2216 article.getDisplayDate(), article.getExpirationDate());
2217
2218 Date displayDate = dateInterval[0];
2219 Date expirationDate = dateInterval[1];
2220
2221 boolean visible = article.isApproved();
2222
2223 if (article.getClassNameId() > 0) {
2224 visible = false;
2225 }
2226
2227 boolean addDraftAssetEntry = false;
2228
2229 if (!article.isApproved() &&
2230 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
2231
2232 int approvedArticlesCount =
2233 journalArticlePersistence.countByG_A_ST(
2234 article.getGroupId(), article.getArticleId(),
2235 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
2236
2237 if (approvedArticlesCount > 0) {
2238 addDraftAssetEntry = true;
2239 }
2240 }
2241
2242 AssetEntry assetEntry = null;
2243
2244 if (addDraftAssetEntry) {
2245 assetEntry = assetEntryLocalService.updateEntry(
2246 userId, article.getGroupId(), JournalArticle.class.getName(),
2247 article.getPrimaryKey(), article.getUuid(),
2248 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
2249 null, null, displayDate, expirationDate, ContentTypes.TEXT_HTML,
2250 article.getTitle(), article.getDescription(),
2251 article.getDescription(), null, article.getLayoutUuid(), 0, 0,
2252 null, false);
2253 }
2254 else {
2255 JournalArticleResource journalArticleResource =
2256 journalArticleResourceLocalService.getArticleResource(
2257 article.getResourcePrimKey());
2258
2259 assetEntry = assetEntryLocalService.updateEntry(
2260 userId, article.getGroupId(), JournalArticle.class.getName(),
2261 journalArticleResource.getResourcePrimKey(),
2262 journalArticleResource.getUuid(), getClassTypeId(article),
2263 assetCategoryIds, assetTagNames, visible, null, null,
2264 displayDate, expirationDate, ContentTypes.TEXT_HTML,
2265 article.getTitle(), article.getDescription(),
2266 article.getDescription(), null, article.getLayoutUuid(), 0, 0,
2267 null, false);
2268 }
2269
2270 assetLinkLocalService.updateLinks(
2271 userId, assetEntry.getEntryId(), assetLinkEntryIds,
2272 AssetLinkConstants.TYPE_RELATED);
2273 }
2274
2275 public JournalArticle updateContent(
2276 long groupId, String articleId, double version, String content)
2277 throws PortalException, SystemException {
2278
2279 JournalArticle article = journalArticlePersistence.findByG_A_V(
2280 groupId, articleId, version);
2281
2282 article.setContent(content);
2283
2284 journalArticlePersistence.update(article, false);
2285
2286 return article;
2287 }
2288
2289 public JournalArticle updateStatus(
2290 long userId, JournalArticle article, int status, String articleURL,
2291 ServiceContext serviceContext)
2292 throws PortalException, SystemException {
2293
2294
2295
2296 User user = userPersistence.findByPrimaryKey(userId);
2297 Date now = new Date();
2298
2299 int oldStatus = article.getStatus();
2300
2301 article.setModifiedDate(serviceContext.getModifiedDate(now));
2302
2303 boolean neverExpire = false;
2304
2305 if (status == WorkflowConstants.STATUS_APPROVED) {
2306 Date expirationDate = article.getExpirationDate();
2307
2308 if ((expirationDate != null) && expirationDate.before(now)) {
2309 neverExpire = true;
2310
2311 article.setExpirationDate(null);
2312 }
2313 }
2314
2315 if (status == WorkflowConstants.STATUS_EXPIRED) {
2316 article.setExpirationDate(now);
2317 }
2318
2319 article.setStatus(status);
2320 article.setStatusByUserId(user.getUserId());
2321 article.setStatusByUserName(user.getFullName());
2322 article.setStatusDate(serviceContext.getModifiedDate(now));
2323
2324 journalArticlePersistence.update(article, false);
2325
2326 if (isLatestVersion(
2327 article.getGroupId(), article.getArticleId(),
2328 article.getVersion())) {
2329
2330 if (status == WorkflowConstants.STATUS_APPROVED) {
2331 updateUrlTitles(
2332 article.getGroupId(), article.getArticleId(),
2333 article.getUrlTitle());
2334
2335
2336
2337 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
2338 (article.getVersion() !=
2339 JournalArticleConstants.VERSION_DEFAULT)) {
2340
2341 AssetEntry draftAssetEntry = null;
2342
2343 try {
2344 draftAssetEntry = assetEntryLocalService.getEntry(
2345 JournalArticle.class.getName(),
2346 article.getPrimaryKey());
2347
2348 Date[] dateInterval = getDateInterval(
2349 article.getGroupId(), article.getArticleId(),
2350 article.getDisplayDate(),
2351 article.getExpirationDate());
2352
2353 Date displayDate = dateInterval[0];
2354 Date expirationDate = dateInterval[1];
2355
2356 long[] assetCategoryIds =
2357 draftAssetEntry.getCategoryIds();
2358 String[] assetTagNames = draftAssetEntry.getTagNames();
2359
2360 List<AssetLink> assetLinks =
2361 assetLinkLocalService.getDirectLinks(
2362 draftAssetEntry.getEntryId(),
2363 AssetLinkConstants.TYPE_RELATED);
2364
2365 long[] assetLinkEntryIds = StringUtil.split(
2366 ListUtil.toString(
2367 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
2368
2369 boolean visible = true;
2370
2371 if (article.getClassNameId() > 0) {
2372 visible = false;
2373 }
2374
2375 AssetEntry assetEntry =
2376 assetEntryLocalService.updateEntry(
2377 userId, article.getGroupId(),
2378 JournalArticle.class.getName(),
2379 article.getResourcePrimKey(), article.getUuid(),
2380 getClassTypeId(article), assetCategoryIds,
2381 assetTagNames, visible, null, null, displayDate,
2382 expirationDate, ContentTypes.TEXT_HTML,
2383 article.getTitle(), article.getDescription(),
2384 article.getDescription(), null,
2385 article.getLayoutUuid(), 0, 0, null, false);
2386
2387 assetLinkLocalService.updateLinks(
2388 userId, assetEntry.getEntryId(),
2389 assetLinkEntryIds, AssetLinkConstants.TYPE_RELATED);
2390
2391 assetEntryLocalService.deleteEntry(
2392 JournalArticle.class.getName(),
2393 article.getPrimaryKey());
2394 }
2395 catch (NoSuchEntryException nsee) {
2396 }
2397 }
2398
2399 if (article.getClassNameId() == 0) {
2400 AssetEntry assetEntry =
2401 assetEntryLocalService.updateVisible(
2402 JournalArticle.class.getName(),
2403 article.getResourcePrimKey(), true);
2404
2405 if (neverExpire) {
2406 assetEntry.setExpirationDate(null);
2407
2408 assetEntryLocalService.updateAssetEntry(
2409 assetEntry, false);
2410 }
2411 }
2412
2413
2414
2415 ExpandoBridge expandoBridge = article.getExpandoBridge();
2416
2417 expandoBridge.setAttributes(serviceContext);
2418
2419
2420
2421 Indexer indexer = IndexerRegistryUtil.getIndexer(
2422 JournalArticle.class);
2423
2424 indexer.reindex(article);
2425 }
2426 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
2427 updatePreviousApprovedArticle(article);
2428 }
2429 }
2430
2431 if (article.getClassNameId() == 0) {
2432
2433
2434
2435 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
2436 ((status == WorkflowConstants.STATUS_APPROVED) ||
2437 (status == WorkflowConstants.STATUS_DENIED))) {
2438
2439 String msg = "granted";
2440
2441 if (status == WorkflowConstants.STATUS_DENIED) {
2442 msg = "denied";
2443 }
2444
2445 try {
2446 PortletPreferences preferences =
2447 ServiceContextUtil.getPortletPreferences(
2448 serviceContext);
2449
2450 sendEmail(
2451 article, articleURL, preferences, msg, serviceContext);
2452 }
2453 catch (Exception e) {
2454 _log.error(
2455 "Unable to send email to notify the change of status " +
2456 " to " + msg + " for article " + article.getId() +
2457 ": " + e.getMessage());
2458 }
2459 }
2460
2461
2462
2463 notifySubscribers(article, serviceContext);
2464 }
2465
2466 return article;
2467 }
2468
2469 public JournalArticle updateStatus(
2470 long userId, long classPK, int status,
2471 ServiceContext serviceContext)
2472 throws PortalException, SystemException {
2473
2474 JournalArticle article = getArticle(classPK);
2475
2476 return updateStatus(userId, article, status, null, serviceContext);
2477 }
2478
2479 public JournalArticle updateStatus(
2480 long userId, long groupId, String articleId, double version,
2481 int status, String articleURL, ServiceContext serviceContext)
2482 throws PortalException, SystemException {
2483
2484 JournalArticle article = journalArticlePersistence.findByG_A_V(
2485 groupId, articleId, version);
2486
2487 return updateStatus(
2488 userId, article, status, articleURL, serviceContext);
2489 }
2490
2491 public void updateTemplateId(
2492 long groupId, long classNameId, String oldTemplateId,
2493 String newTemplateId)
2494 throws SystemException {
2495
2496 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
2497 groupId, classNameId, oldTemplateId);
2498
2499 for (JournalArticle article : articles) {
2500 article.setTemplateId(newTemplateId);
2501
2502 journalArticlePersistence.update(article, false);
2503 }
2504 }
2505
2506 protected void checkStructure(Document contentDoc, Element root)
2507 throws PortalException {
2508
2509 for (Element el : root.elements()) {
2510 checkStructureField(el, contentDoc);
2511
2512 checkStructure(contentDoc, el);
2513 }
2514 }
2515
2516 protected void checkStructure(JournalArticle article)
2517 throws DocumentException, PortalException, SystemException {
2518
2519 Group companyGroup = groupLocalService.getCompanyGroup(
2520 article.getCompanyId());
2521
2522 JournalStructure structure = null;
2523
2524 try {
2525 structure = journalStructurePersistence.findByG_S(
2526 article.getGroupId(), article.getStructureId());
2527 }
2528 catch (NoSuchStructureException nsse) {
2529 structure = journalStructurePersistence.findByG_S(
2530 companyGroup.getGroupId(), article.getStructureId());
2531 }
2532
2533 String content = GetterUtil.getString(article.getContent());
2534
2535 Document contentDoc = SAXReaderUtil.read(content);
2536 Document xsdDoc = SAXReaderUtil.read(structure.getXsd());
2537
2538 try {
2539 checkStructure(contentDoc, xsdDoc.getRootElement());
2540 }
2541 catch (StructureXsdException sxsde) {
2542 long groupId = article.getGroupId();
2543 String articleId = article.getArticleId();
2544 double version = article.getVersion();
2545
2546 if (_log.isWarnEnabled()) {
2547 _log.warn(
2548 "Article {groupId=" + groupId + ", articleId=" +
2549 articleId + ", version=" + version +
2550 "} has content that does not match its " +
2551 "structure: " + sxsde.getMessage());
2552 }
2553 }
2554 }
2555
2556 protected void checkStructureField(Element el, Document contentDoc)
2557 throws PortalException {
2558
2559 StringBuilder elPath = new StringBuilder();
2560
2561 elPath.append(el.attributeValue("name"));
2562
2563 Element elParent = el.getParent();
2564
2565 for (;;) {
2566 if ((elParent == null) || (elParent.getName().equals("root"))) {
2567 break;
2568 }
2569
2570 elPath.insert(
2571 0, elParent.attributeValue("name") + StringPool.COMMA);
2572
2573 elParent = elParent.getParent();
2574 }
2575
2576 String[] elPathNames = StringUtil.split(elPath.toString());
2577
2578 Element contentEl = contentDoc.getRootElement();
2579
2580 for (String _elPathName : elPathNames) {
2581 boolean foundEl = false;
2582
2583 for (Element tempEl : contentEl.elements()) {
2584 if (_elPathName.equals(
2585 tempEl.attributeValue("name", StringPool.BLANK))) {
2586
2587 contentEl = tempEl;
2588 foundEl = true;
2589
2590 break;
2591 }
2592 }
2593
2594 if (!foundEl) {
2595 String elType = contentEl.attributeValue(
2596 "type", StringPool.BLANK);
2597
2598 if (!elType.equals("list") && !elType.equals("multi-list")) {
2599 throw new StructureXsdException(elPath.toString());
2600 }
2601
2602 break;
2603 }
2604 }
2605 }
2606
2607 protected void copyArticleImages(
2608 JournalArticle oldArticle, JournalArticle newArticle)
2609 throws Exception {
2610
2611 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
2612
2613 XPath xPathSelector = SAXReaderUtil.createXPath(
2614 "
2615
2616 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
2617
2618 for (Node imageNode : imageNodes) {
2619 Element imageEl = (Element)imageNode;
2620
2621 String instanceId = imageEl.attributeValue("instance-id");
2622 String name = imageEl.attributeValue("name");
2623
2624 List<Element> dynamicContentEls = imageEl.elements(
2625 "dynamic-content");
2626
2627 for (Element dynamicContentEl : dynamicContentEls) {
2628 long imageId = GetterUtil.getLong(
2629 dynamicContentEl.attributeValue("id"));
2630 String languageId = dynamicContentEl.attributeValue(
2631 "language-id");
2632
2633 Image oldImage = null;
2634
2635 try {
2636 oldImage = imageLocalService.getImage(imageId);
2637 }
2638 catch (NoSuchImageException nsie) {
2639 continue;
2640 }
2641
2642 imageId = journalArticleImageLocalService.getArticleImageId(
2643 newArticle.getGroupId(), newArticle.getArticleId(),
2644 newArticle.getVersion(), instanceId, name, languageId);
2645
2646 imageLocalService.updateImage(imageId, oldImage.getTextObj());
2647
2648 String elContent =
2649 "/image/journal/article?img_id=" + imageId + "&t=" +
2650 WebServerServletTokenUtil.getToken(imageId);
2651
2652 dynamicContentEl.setText(elContent);
2653 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
2654 }
2655 }
2656
2657 newArticle.setContent(contentDoc.formattedString());
2658 }
2659
2660 protected void format(
2661 User user, long groupId, String articleId, double version,
2662 boolean incrementVersion, Element root, Map<String, byte[]> images)
2663 throws PortalException, SystemException {
2664
2665 for (Element element : root.elements()) {
2666 String elInstanceId = element.attributeValue(
2667 "instance-id", StringPool.BLANK);
2668 String elName = element.attributeValue("name", StringPool.BLANK);
2669 String elType = element.attributeValue("type", StringPool.BLANK);
2670
2671 if (elType.equals("image")) {
2672 formatImage(
2673 groupId, articleId, version, incrementVersion, element,
2674 elInstanceId, elName, images);
2675 }
2676 else if (elType.equals("text_area") || elType.equals("text") ||
2677 elType.equals("text_box")) {
2678
2679 List<Element> dynamicContentElements = element.elements(
2680 "dynamic-content");
2681
2682 for (Element dynamicContentElement : dynamicContentElements) {
2683 String dynamicContent = dynamicContentElement.getText();
2684
2685 if (Validator.isNotNull(dynamicContent)) {
2686 dynamicContent = SanitizerUtil.sanitize(
2687 user.getCompanyId(), groupId, user.getUserId(),
2688 JournalArticle.class.getName(), 0,
2689 ContentTypes.TEXT_HTML, dynamicContent);
2690
2691 dynamicContentElement.setText(dynamicContent);
2692 }
2693 }
2694 }
2695
2696 format(
2697 user, groupId, articleId, version, incrementVersion, element,
2698 images);
2699 }
2700 }
2701
2702 protected String format(
2703 User user, long groupId, String articleId, double version,
2704 boolean incrementVersion, String content, String structureId,
2705 Map<String, byte[]> images)
2706 throws PortalException, SystemException {
2707
2708 Document document = null;
2709
2710 try {
2711 document = SAXReaderUtil.read(content);
2712
2713 Element rootElement = document.getRootElement();
2714
2715 if (Validator.isNotNull(structureId)) {
2716 format(
2717 user, groupId, articleId, version, incrementVersion,
2718 rootElement, images);
2719 }
2720 else {
2721 List<Element> staticContentElements = rootElement.elements(
2722 "static-content");
2723
2724 for (Element staticContentElement : staticContentElements) {
2725 String staticContent = staticContentElement.getText();
2726
2727 staticContent = SanitizerUtil.sanitize(
2728 user.getCompanyId(), groupId, user.getUserId(),
2729 JournalArticle.class.getName(), 0,
2730 ContentTypes.TEXT_HTML, staticContent);
2731
2732 staticContentElement.setText(staticContent);
2733 }
2734 }
2735
2736 content = DDMXMLUtil.formatXML(document);
2737 }
2738 catch (DocumentException de) {
2739 _log.error(de);
2740 }
2741 catch (IOException ioe) {
2742 _log.error(ioe);
2743 }
2744
2745 content = HtmlUtil.replaceMsWordCharacters(content);
2746
2747 return content;
2748 }
2749
2750 protected void formatImage(
2751 long groupId, String articleId, double version,
2752 boolean incrementVersion, Element el, String elInstanceId,
2753 String elName, Map<String, byte[]> images)
2754 throws PortalException, SystemException {
2755
2756 List<Element> imageContents = el.elements("dynamic-content");
2757
2758 for (Element dynamicContent : imageContents) {
2759 String elLanguage = dynamicContent.attributeValue(
2760 "language-id", StringPool.BLANK);
2761
2762 if (!elLanguage.equals(StringPool.BLANK)) {
2763 elLanguage = "_" + elLanguage;
2764 }
2765
2766 long imageId =
2767 journalArticleImageLocalService.getArticleImageId(
2768 groupId, articleId, version, elInstanceId, elName,
2769 elLanguage);
2770
2771 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
2772
2773 long oldImageId = 0;
2774
2775 if ((oldVersion >= 1) && incrementVersion) {
2776 oldImageId =
2777 journalArticleImageLocalService.getArticleImageId(
2778 groupId, articleId, oldVersion, elInstanceId, elName,
2779 elLanguage);
2780 }
2781
2782 String elContent =
2783 "/image/journal/article?img_id=" + imageId + "&t=" +
2784 WebServerServletTokenUtil.getToken(imageId);
2785
2786 if (dynamicContent.getText().equals("delete")) {
2787 dynamicContent.setText(StringPool.BLANK);
2788
2789 imageLocalService.deleteImage(imageId);
2790
2791 String defaultElLanguage = "";
2792
2793 if (!Validator.isNotNull(elLanguage)) {
2794 defaultElLanguage =
2795 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2796 }
2797
2798 long defaultImageId =
2799 journalArticleImageLocalService.getArticleImageId(
2800 groupId, articleId, version, elInstanceId, elName,
2801 defaultElLanguage);
2802
2803 imageLocalService.deleteImage(defaultImageId);
2804
2805 continue;
2806 }
2807
2808 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
2809
2810 if ((bytes != null) && (bytes.length > 0)) {
2811 dynamicContent.setText(elContent);
2812 dynamicContent.addAttribute("id", String.valueOf(imageId));
2813
2814 imageLocalService.updateImage(imageId, bytes);
2815
2816 continue;
2817 }
2818
2819 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
2820 (incrementVersion)) {
2821
2822 Image oldImage = null;
2823
2824 if (oldImageId > 0) {
2825 oldImage = imageLocalService.getImage(oldImageId);
2826 }
2827
2828 if (oldImage != null) {
2829 dynamicContent.setText(elContent);
2830 dynamicContent.addAttribute("id", String.valueOf(imageId));
2831
2832 bytes = oldImage.getTextObj();
2833
2834 imageLocalService.updateImage(imageId, bytes);
2835 }
2836
2837 continue;
2838 }
2839
2840 Image image = imageLocalService.getImage(imageId);
2841
2842 if (image != null) {
2843 dynamicContent.setText(elContent);
2844 dynamicContent.addAttribute("id", String.valueOf(imageId));
2845
2846 continue;
2847 }
2848
2849 long contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2850 dynamicContent.getText(), "img_id"));
2851
2852 if (contentImageId <= 0) {
2853 contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2854 dynamicContent.getText(), "img_id", false));
2855 }
2856
2857 if (contentImageId > 0) {
2858 image = imageLocalService.getImage(contentImageId);
2859
2860 if (image != null) {
2861 dynamicContent.addAttribute(
2862 "id", String.valueOf(contentImageId));
2863
2864 continue;
2865 }
2866 }
2867
2868 String defaultElLanguage = "";
2869
2870 if (!Validator.isNotNull(elLanguage)) {
2871 defaultElLanguage =
2872 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2873 }
2874
2875 long defaultImageId =
2876 journalArticleImageLocalService.getArticleImageId(
2877 groupId, articleId, version, elInstanceId, elName,
2878 defaultElLanguage);
2879
2880 Image defaultImage = imageLocalService.getImage(defaultImageId);
2881
2882 if (defaultImage != null) {
2883 dynamicContent.setText(elContent);
2884 dynamicContent.addAttribute(
2885 "id", String.valueOf(defaultImageId));
2886
2887 bytes = defaultImage.getTextObj();
2888
2889 imageLocalService.updateImage(defaultImageId, bytes);
2890
2891 continue;
2892 }
2893
2894 if (Validator.isNotNull(elLanguage)) {
2895 dynamicContent.setText(StringPool.BLANK);
2896 }
2897 }
2898 }
2899
2900 protected long getClassTypeId(JournalArticle article) {
2901 long classTypeId = 0;
2902
2903 try {
2904 JournalStructure structure = journalStructurePersistence.fetchByG_S(
2905 article.getGroupId(), article.getStructureId());
2906
2907 if (structure == null) {
2908 Group companyGroup = groupLocalService.getCompanyGroup(
2909 article.getCompanyId());
2910
2911 structure = journalStructurePersistence.fetchByG_S(
2912 companyGroup.getGroupId(), article.getStructureId());
2913 }
2914
2915 if (structure != null) {
2916 classTypeId = structure.getId();
2917 }
2918 }
2919 catch (Exception e) {
2920 _log.error(e, e);
2921 }
2922
2923 return classTypeId;
2924 }
2925
2926 protected Date[] getDateInterval(
2927 long groupId, String articleId, Date earliestDisplayDate,
2928 Date latestExpirationDate)
2929 throws SystemException {
2930
2931 Date[] dateInterval = new Date[2];
2932
2933 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2934 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2935
2936 boolean expiringArticle = true;
2937
2938 if (latestExpirationDate == null) {
2939 expiringArticle = false;
2940 }
2941
2942 for (JournalArticle article : articles) {
2943 if ((earliestDisplayDate == null) ||
2944 ((article.getDisplayDate() != null) &&
2945 earliestDisplayDate.after(article.getDisplayDate()))) {
2946
2947 earliestDisplayDate = article.getDisplayDate();
2948 }
2949
2950 if (expiringArticle &&
2951 ((latestExpirationDate == null) ||
2952 ((article.getExpirationDate() != null) &&
2953 latestExpirationDate.before(article.getExpirationDate())))) {
2954
2955 latestExpirationDate = article.getExpirationDate();
2956 }
2957
2958 if (expiringArticle && (article.getExpirationDate() == null) &&
2959 (latestExpirationDate != null)) {
2960
2961 expiringArticle = false;
2962 }
2963 }
2964
2965 dateInterval[0] = earliestDisplayDate;
2966 dateInterval[1] = latestExpirationDate;
2967
2968 return dateInterval;
2969 }
2970
2971 protected String getUniqueUrlTitle(
2972 long id, long groupId, String articleId, String title)
2973 throws PortalException, SystemException {
2974
2975 String urlTitle = JournalUtil.getUrlTitle(id, title);
2976
2977 String newUrlTitle = ModelHintsUtil.trimString(
2978 JournalArticle.class.getName(), "urlTitle", urlTitle);
2979
2980 for (int i = 1;; i++) {
2981 JournalArticle article = null;
2982
2983 try {
2984 article = getArticleByUrlTitle(groupId, newUrlTitle);
2985 }
2986 catch (NoSuchArticleException nsae) {
2987 }
2988
2989 if ((article == null) || article.getArticleId().equals(articleId)) {
2990 break;
2991 }
2992 else {
2993 String suffix = StringPool.DASH + i;
2994
2995 String prefix = newUrlTitle;
2996
2997 if (newUrlTitle.length() > suffix.length()) {
2998 prefix = newUrlTitle.substring(
2999 0, newUrlTitle.length() - suffix.length());
3000 }
3001
3002 newUrlTitle = prefix + suffix;
3003 }
3004 }
3005
3006 return newUrlTitle;
3007 }
3008
3009 protected void notifySubscribers(
3010 JournalArticle article, ServiceContext serviceContext)
3011 throws PortalException, SystemException {
3012
3013 if (!article.isApproved()) {
3014 return;
3015 }
3016
3017 String articleURL = PortalUtil.getControlPanelFullURL(
3018 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
3019
3020 if (Validator.isNull(articleURL)) {
3021 return;
3022 }
3023
3024 PortletPreferences preferences =
3025 ServiceContextUtil.getPortletPreferences(serviceContext);
3026
3027 if (preferences == null) {
3028 long ownerId = article.getGroupId();
3029 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
3030 long plid = PortletKeys.PREFS_PLID_SHARED;
3031 String portletId = PortletKeys.JOURNAL;
3032 String defaultPreferences = null;
3033
3034 preferences = portletPreferencesLocalService.getPreferences(
3035 article.getCompanyId(), ownerId, ownerType, plid, portletId,
3036 defaultPreferences);
3037 }
3038
3039 if ((article.getVersion() == 1.0) &&
3040 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
3041 }
3042 else if ((article.getVersion() != 1.0) &&
3043 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
3044 }
3045 else {
3046 return;
3047 }
3048
3049 String fromName = JournalUtil.getEmailFromName(
3050 preferences, article.getCompanyId());
3051 String fromAddress = JournalUtil.getEmailFromAddress(
3052 preferences, article.getCompanyId());
3053
3054 String subject = null;
3055 String body = null;
3056
3057 if (article.getVersion() == 1.0) {
3058 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
3059 body = JournalUtil.getEmailArticleAddedBody(preferences);
3060 }
3061 else {
3062 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
3063 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
3064 }
3065
3066 SubscriptionSender subscriptionSender = new SubscriptionSender();
3067
3068 subscriptionSender.setBody(body);
3069 subscriptionSender.setCompanyId(article.getCompanyId());
3070 subscriptionSender.setContextAttributes(
3071 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
3072 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
3073 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
3074 subscriptionSender.setContextUserPrefix("ARTICLE");
3075 subscriptionSender.setFrom(fromAddress, fromName);
3076 subscriptionSender.setHtmlFormat(true);
3077 subscriptionSender.setMailId("journal_article", article.getId());
3078 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
3079 subscriptionSender.setReplyToAddress(fromAddress);
3080 subscriptionSender.setScopeGroupId(article.getGroupId());
3081 subscriptionSender.setServiceContext(serviceContext);
3082 subscriptionSender.setSubject(subject);
3083 subscriptionSender.setUserId(article.getUserId());
3084
3085 subscriptionSender.addPersistedSubscribers(
3086 JournalArticle.class.getName(), article.getGroupId());
3087
3088 subscriptionSender.flushNotificationsAsync();
3089 }
3090
3091 protected void saveImages(
3092 boolean smallImage, long smallImageId, File smallImageFile,
3093 byte[] smallImageBytes)
3094 throws PortalException, SystemException {
3095
3096 if (smallImage) {
3097 if ((smallImageFile != null) && (smallImageBytes != null)) {
3098 imageLocalService.updateImage(smallImageId, smallImageBytes);
3099 }
3100 }
3101 else {
3102 imageLocalService.deleteImage(smallImageId);
3103 }
3104 }
3105
3106 protected void sendEmail(
3107 JournalArticle article, String articleURL,
3108 PortletPreferences preferences, String emailType,
3109 ServiceContext serviceContext)
3110 throws PortalException, SystemException {
3111
3112 if (preferences == null) {
3113 return;
3114 }
3115 else if (emailType.equals("denied") &&
3116 JournalUtil.getEmailArticleApprovalDeniedEnabled(
3117 preferences)) {
3118 }
3119 else if (emailType.equals("granted") &&
3120 JournalUtil.getEmailArticleApprovalGrantedEnabled(
3121 preferences)) {
3122 }
3123 else if (emailType.equals("requested") &&
3124 JournalUtil.getEmailArticleApprovalRequestedEnabled(
3125 preferences)) {
3126 }
3127 else if (emailType.equals("review") &&
3128 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
3129 }
3130 else {
3131 return;
3132 }
3133
3134 Company company = companyPersistence.findByPrimaryKey(
3135 article.getCompanyId());
3136
3137 User user = userPersistence.findByPrimaryKey(article.getUserId());
3138
3139 articleURL +=
3140 "&groupId=" + article.getGroupId() + "&articleId=" +
3141 article.getArticleId() + "&version=" + article.getVersion();
3142
3143 String fromName = JournalUtil.getEmailFromName(
3144 preferences, article.getCompanyId());
3145 String fromAddress = JournalUtil.getEmailFromAddress(
3146 preferences, article.getCompanyId());
3147
3148 String toName = user.getFullName();
3149 String toAddress = user.getEmailAddress();
3150
3151 if (emailType.equals("requested") || emailType.equals("review")) {
3152 String tempToName = fromName;
3153 String tempToAddress = fromAddress;
3154
3155 fromName = toName;
3156 fromAddress = toAddress;
3157
3158 toName = tempToName;
3159 toAddress = tempToAddress;
3160 }
3161
3162 String subject = null;
3163 String body = null;
3164
3165 if (emailType.equals("denied")) {
3166 subject =
3167 JournalUtil.getEmailArticleApprovalDeniedSubject(preferences);
3168 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
3169 }
3170 else if (emailType.equals("granted")) {
3171 subject =
3172 JournalUtil.getEmailArticleApprovalGrantedSubject(preferences);
3173 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
3174 }
3175 else if (emailType.equals("requested")) {
3176 subject =
3177 JournalUtil.getEmailArticleApprovalRequestedSubject(
3178 preferences);
3179 body = JournalUtil.getEmailArticleApprovalRequestedBody(
3180 preferences);
3181 }
3182 else if (emailType.equals("review")) {
3183 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
3184 body = JournalUtil.getEmailArticleReviewBody(preferences);
3185 }
3186
3187 SubscriptionSender subscriptionSender = new SubscriptionSender();
3188
3189 subscriptionSender.setBody(body);
3190 subscriptionSender.setCompanyId(company.getCompanyId());
3191 subscriptionSender.setContextAttributes(
3192 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
3193 article.getTitle(), "[$ARTICLE_URL$]", articleURL,
3194 "[$ARTICLE_USER_NAME$]", article.getUserName(),
3195 "[$ARTICLE_VERSION$]", article.getVersion());
3196 subscriptionSender.setContextUserPrefix("ARTICLE");
3197 subscriptionSender.setFrom(fromAddress, fromName);
3198 subscriptionSender.setHtmlFormat(true);
3199 subscriptionSender.setMailId("journal_article", article.getId());
3200 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
3201 subscriptionSender.setScopeGroupId(article.getGroupId());
3202 subscriptionSender.setServiceContext(serviceContext);
3203 subscriptionSender.setSubject(subject);
3204 subscriptionSender.setUserId(article.getUserId());
3205
3206 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
3207
3208 subscriptionSender.flushNotificationsAsync();
3209 }
3210
3211 protected void updatePreviousApprovedArticle(JournalArticle article)
3212 throws PortalException, SystemException {
3213
3214 List<JournalArticle> approvedArticles =
3215 journalArticlePersistence.findByG_A_ST(
3216 article.getGroupId(), article.getArticleId(),
3217 WorkflowConstants.STATUS_APPROVED, 0, 2);
3218
3219 if (approvedArticles.isEmpty() ||
3220 ((approvedArticles.size() == 1) &&
3221 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
3222
3223 if (article.isIndexable()) {
3224 Indexer indexer = IndexerRegistryUtil.getIndexer(
3225 JournalArticle.class);
3226
3227 indexer.delete(article);
3228 }
3229
3230 assetEntryLocalService.updateVisible(
3231 JournalArticle.class.getName(), article.getResourcePrimKey(),
3232 false);
3233 }
3234 else {
3235 JournalArticle previousApprovedArticle = approvedArticles.get(0);
3236
3237 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
3238 previousApprovedArticle = approvedArticles.get(1);
3239 }
3240
3241 if (article.isIndexable()) {
3242 Indexer indexer = IndexerRegistryUtil.getIndexer(
3243 JournalArticle.class);
3244
3245 indexer.reindex(previousApprovedArticle);
3246 }
3247 }
3248 }
3249
3250 protected void updateUrlTitles(
3251 long groupId, String articleId, String urlTitle)
3252 throws SystemException {
3253
3254 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3255 groupId, articleId);
3256
3257 for (JournalArticle article : articles) {
3258 if (!article.getUrlTitle().equals(urlTitle)) {
3259 article.setUrlTitle(urlTitle);
3260
3261 journalArticlePersistence.update(article, false);
3262 }
3263 }
3264 }
3265
3266 protected void validate(
3267 long companyId, long groupId, long classNameId,
3268 Map<Locale, String> titleMap, String content, String type,
3269 String structureId, String templateId, boolean smallImage,
3270 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
3271 throws PortalException, SystemException {
3272
3273 Locale defaultLocale = LocaleUtil.fromLanguageId(
3274 LocalizationUtil.getDefaultLocale(content));
3275
3276 if ((classNameId == 0) &&
3277 (titleMap.isEmpty() ||
3278 Validator.isNull(titleMap.get(defaultLocale)))) {
3279
3280 throw new ArticleTitleException();
3281 }
3282 else if (Validator.isNull(type)) {
3283 throw new ArticleTypeException();
3284 }
3285
3286 validateContent(content);
3287
3288 if (Validator.isNotNull(structureId)) {
3289 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
3290
3291 try {
3292 journalStructurePersistence.findByG_S(groupId, structureId);
3293 }
3294 catch (NoSuchStructureException nsse) {
3295 journalStructurePersistence.findByG_S(
3296 companyGroup.getGroupId(), structureId);
3297 }
3298
3299 JournalTemplate template = null;
3300
3301 if (Validator.isNotNull(templateId)) {
3302 try {
3303 template = journalTemplatePersistence.findByG_T(
3304 groupId, templateId);
3305 }
3306 catch (NoSuchTemplateException nste) {
3307 template = journalTemplatePersistence.findByG_T(
3308 companyGroup.getGroupId(), templateId);
3309 }
3310
3311 if (!template.getStructureId().equals(structureId)) {
3312 throw new NoSuchTemplateException();
3313 }
3314 }
3315 else if (classNameId == 0) {
3316 throw new NoSuchTemplateException();
3317 }
3318 }
3319
3320 String[] imageExtensions = PrefsPropsUtil.getStringArray(
3321 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
3322
3323 if (smallImage && Validator.isNull(smallImageURL) &&
3324 (smallImageFile != null) && (smallImageBytes != null)) {
3325
3326 String smallImageName = smallImageFile.getName();
3327
3328 if (smallImageName != null) {
3329 boolean validSmallImageExtension = false;
3330
3331 for (String _imageExtension : imageExtensions) {
3332 if (StringPool.STAR.equals(_imageExtension) ||
3333 StringUtil.endsWith(smallImageName, _imageExtension)) {
3334
3335 validSmallImageExtension = true;
3336
3337 break;
3338 }
3339 }
3340
3341 if (!validSmallImageExtension) {
3342 throw new ArticleSmallImageNameException(smallImageName);
3343 }
3344 }
3345
3346 long smallImageMaxSize = PrefsPropsUtil.getLong(
3347 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
3348
3349 if ((smallImageMaxSize > 0) &&
3350 ((smallImageBytes == null) ||
3351 (smallImageBytes.length > smallImageMaxSize))) {
3352
3353 throw new ArticleSmallImageSizeException();
3354 }
3355 }
3356 }
3357
3358 protected void validate(
3359 long companyId, long groupId, long classNameId, String articleId,
3360 boolean autoArticleId, double version, Map<Locale, String> titleMap,
3361 String content, String type, String structureId, String templateId,
3362 boolean smallImage, String smallImageURL, File smallImageFile,
3363 byte[] smallImageBytes)
3364 throws PortalException, SystemException {
3365
3366 if (!autoArticleId) {
3367 validate(groupId, articleId);
3368 }
3369
3370 validate(
3371 companyId, groupId, classNameId, titleMap, content, type,
3372 structureId, templateId, smallImage, smallImageURL, smallImageFile,
3373 smallImageBytes);
3374 }
3375
3376 protected void validate(long groupId, String articleId)
3377 throws PortalException, SystemException {
3378
3379 if ((Validator.isNull(articleId)) ||
3380 (articleId.indexOf(CharPool.SPACE) != -1)) {
3381
3382 throw new ArticleIdException();
3383 }
3384
3385 if (journalArticlePersistence.countByG_A(groupId, articleId) > 0) {
3386 throw new DuplicateArticleIdException();
3387 }
3388 }
3389
3390 protected void validateContent(String content) throws PortalException {
3391 if (Validator.isNull(content)) {
3392 throw new ArticleContentException();
3393 }
3394
3395 try {
3396 SAXReaderUtil.read(content);
3397 }
3398 catch (DocumentException de) {
3399 throw new ArticleContentException();
3400 }
3401 }
3402
3403 private static long _JOURNAL_ARTICLE_CHECK_INTERVAL =
3404 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
3405
3406 private static Log _log = LogFactoryUtil.getLog(
3407 JournalArticleLocalServiceImpl.class);
3408
3409 }