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.getAddGroupPermissions() ||
258 serviceContext.getAddGuestPermissions()) {
259
260 addArticleResources(
261 article, serviceContext.getAddGroupPermissions(),
262 serviceContext.getAddGuestPermissions());
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 WorkflowConstants.STATUS_APPROVED);
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) ||
2567 (elParent.getName().equals("root"))) {
2568
2569 break;
2570 }
2571
2572 elPath.insert(
2573 0, elParent.attributeValue("name") + StringPool.COMMA);
2574
2575 elParent = elParent.getParent();
2576 }
2577
2578 String[] elPathNames = StringUtil.split(elPath.toString());
2579
2580 Element contentEl = contentDoc.getRootElement();
2581
2582 for (String _elPathName : elPathNames) {
2583 boolean foundEl = false;
2584
2585 for (Element tempEl : contentEl.elements()) {
2586 if (_elPathName.equals(
2587 tempEl.attributeValue("name", StringPool.BLANK))) {
2588
2589 contentEl = tempEl;
2590 foundEl = true;
2591
2592 break;
2593 }
2594 }
2595
2596 if (!foundEl) {
2597 String elType = contentEl.attributeValue(
2598 "type", StringPool.BLANK);
2599
2600 if (!elType.equals("list") && !elType.equals("multi-list")) {
2601 throw new StructureXsdException(elPath.toString());
2602 }
2603
2604 break;
2605 }
2606 }
2607 }
2608
2609 protected void copyArticleImages(
2610 JournalArticle oldArticle, JournalArticle newArticle)
2611 throws Exception {
2612
2613 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
2614
2615 XPath xPathSelector = SAXReaderUtil.createXPath(
2616 "
2617
2618 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
2619
2620 for (Node imageNode : imageNodes) {
2621 Element imageEl = (Element)imageNode;
2622
2623 String instanceId = imageEl.attributeValue("instance-id");
2624 String name = imageEl.attributeValue("name");
2625
2626 List<Element> dynamicContentEls = imageEl.elements(
2627 "dynamic-content");
2628
2629 for (Element dynamicContentEl : dynamicContentEls) {
2630 long imageId = GetterUtil.getLong(
2631 dynamicContentEl.attributeValue("id"));
2632 String languageId = dynamicContentEl.attributeValue(
2633 "language-id");
2634
2635 Image oldImage = null;
2636
2637 try {
2638 oldImage = imageLocalService.getImage(imageId);
2639 }
2640 catch (NoSuchImageException nsie) {
2641 continue;
2642 }
2643
2644 imageId = journalArticleImageLocalService.getArticleImageId(
2645 newArticle.getGroupId(), newArticle.getArticleId(),
2646 newArticle.getVersion(), instanceId, name, languageId);
2647
2648 imageLocalService.updateImage(imageId, oldImage.getTextObj());
2649
2650 String elContent =
2651 "/image/journal/article?img_id=" + imageId + "&t=" +
2652 WebServerServletTokenUtil.getToken(imageId);
2653
2654 dynamicContentEl.setText(elContent);
2655 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
2656 }
2657 }
2658
2659 newArticle.setContent(contentDoc.formattedString());
2660 }
2661
2662 protected void format(
2663 User user, long groupId, String articleId, double version,
2664 boolean incrementVersion, Element root, Map<String, byte[]> images)
2665 throws PortalException, SystemException {
2666
2667 for (Element element : root.elements()) {
2668 String elInstanceId = element.attributeValue(
2669 "instance-id", StringPool.BLANK);
2670 String elName = element.attributeValue("name", StringPool.BLANK);
2671 String elType = element.attributeValue("type", StringPool.BLANK);
2672
2673 if (elType.equals("image")) {
2674 formatImage(
2675 groupId, articleId, version, incrementVersion, element,
2676 elInstanceId, elName, images);
2677 }
2678 else if (elType.equals("text_area") || elType.equals("text") ||
2679 elType.equals("text_box")) {
2680
2681 List<Element> dynamicContentElements = element.elements(
2682 "dynamic-content");
2683
2684 for (Element dynamicContentElement : dynamicContentElements) {
2685 String dynamicContent = dynamicContentElement.getText();
2686
2687 if (Validator.isNotNull(dynamicContent)) {
2688 dynamicContent = SanitizerUtil.sanitize(
2689 user.getCompanyId(), groupId, user.getUserId(),
2690 JournalArticle.class.getName(), 0,
2691 ContentTypes.TEXT_HTML, dynamicContent);
2692
2693 dynamicContentElement.setText(dynamicContent);
2694 }
2695 }
2696 }
2697
2698 format(
2699 user, groupId, articleId, version, incrementVersion, element,
2700 images);
2701 }
2702 }
2703
2704 protected String format(
2705 User user, long groupId, String articleId, double version,
2706 boolean incrementVersion, String content, String structureId,
2707 Map<String, byte[]> images)
2708 throws PortalException, SystemException {
2709
2710 Document document = null;
2711
2712 try {
2713 document = SAXReaderUtil.read(content);
2714
2715 Element rootElement = document.getRootElement();
2716
2717 if (Validator.isNotNull(structureId)) {
2718 format(
2719 user, groupId, articleId, version, incrementVersion,
2720 rootElement, images);
2721 }
2722 else {
2723 List<Element> staticContentElements = rootElement.elements(
2724 "static-content");
2725
2726 for (Element staticContentElement : staticContentElements) {
2727 String staticContent = staticContentElement.getText();
2728
2729 staticContent = SanitizerUtil.sanitize(
2730 user.getCompanyId(), groupId, user.getUserId(),
2731 JournalArticle.class.getName(), 0,
2732 ContentTypes.TEXT_HTML, staticContent);
2733
2734 staticContentElement.setText(staticContent);
2735 }
2736 }
2737
2738 content = DDMXMLUtil.formatXML(document);
2739 }
2740 catch (DocumentException de) {
2741 _log.error(de);
2742 }
2743 catch (IOException ioe) {
2744 _log.error(ioe);
2745 }
2746
2747 content = HtmlUtil.replaceMsWordCharacters(content);
2748
2749 return content;
2750 }
2751
2752 protected void formatImage(
2753 long groupId, String articleId, double version,
2754 boolean incrementVersion, Element el, String elInstanceId,
2755 String elName, Map<String, byte[]> images)
2756 throws PortalException, SystemException {
2757
2758 List<Element> imageContents = el.elements("dynamic-content");
2759
2760 for (Element dynamicContent : imageContents) {
2761 String elLanguage = dynamicContent.attributeValue(
2762 "language-id", StringPool.BLANK);
2763
2764 if (!elLanguage.equals(StringPool.BLANK)) {
2765 elLanguage = "_" + elLanguage;
2766 }
2767
2768 long imageId =
2769 journalArticleImageLocalService.getArticleImageId(
2770 groupId, articleId, version, elInstanceId, elName,
2771 elLanguage);
2772
2773 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
2774
2775 long oldImageId = 0;
2776
2777 if ((oldVersion >= 1) && incrementVersion) {
2778 oldImageId =
2779 journalArticleImageLocalService.getArticleImageId(
2780 groupId, articleId, oldVersion, elInstanceId, elName,
2781 elLanguage);
2782 }
2783
2784 String elContent =
2785 "/image/journal/article?img_id=" + imageId + "&t=" +
2786 WebServerServletTokenUtil.getToken(imageId);
2787
2788 if (dynamicContent.getText().equals("delete")) {
2789 dynamicContent.setText(StringPool.BLANK);
2790
2791 imageLocalService.deleteImage(imageId);
2792
2793 String defaultElLanguage = "";
2794
2795 if (!Validator.isNotNull(elLanguage)) {
2796 defaultElLanguage =
2797 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2798 }
2799
2800 long defaultImageId =
2801 journalArticleImageLocalService.getArticleImageId(
2802 groupId, articleId, version, elInstanceId, elName,
2803 defaultElLanguage);
2804
2805 imageLocalService.deleteImage(defaultImageId);
2806
2807 continue;
2808 }
2809
2810 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
2811
2812 if ((bytes != null) && (bytes.length > 0)) {
2813 dynamicContent.setText(elContent);
2814 dynamicContent.addAttribute("id", String.valueOf(imageId));
2815
2816 imageLocalService.updateImage(imageId, bytes);
2817
2818 continue;
2819 }
2820
2821 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
2822 (incrementVersion)) {
2823
2824 Image oldImage = null;
2825
2826 if (oldImageId > 0) {
2827 oldImage = imageLocalService.getImage(oldImageId);
2828 }
2829
2830 if (oldImage != null) {
2831 dynamicContent.setText(elContent);
2832 dynamicContent.addAttribute("id", String.valueOf(imageId));
2833
2834 bytes = oldImage.getTextObj();
2835
2836 imageLocalService.updateImage(imageId, bytes);
2837 }
2838
2839 continue;
2840 }
2841
2842 Image image = imageLocalService.getImage(imageId);
2843
2844 if (image != null) {
2845 dynamicContent.setText(elContent);
2846 dynamicContent.addAttribute("id", String.valueOf(imageId));
2847
2848 continue;
2849 }
2850
2851 long contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2852 dynamicContent.getText(), "img_id"));
2853
2854 if (contentImageId <= 0) {
2855 contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2856 dynamicContent.getText(), "img_id", false));
2857 }
2858
2859 if (contentImageId > 0) {
2860 image = imageLocalService.getImage(contentImageId);
2861
2862 if (image != null) {
2863 dynamicContent.addAttribute(
2864 "id", String.valueOf(contentImageId));
2865
2866 continue;
2867 }
2868 }
2869
2870 String defaultElLanguage = "";
2871
2872 if (!Validator.isNotNull(elLanguage)) {
2873 defaultElLanguage =
2874 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2875 }
2876
2877 long defaultImageId =
2878 journalArticleImageLocalService.getArticleImageId(
2879 groupId, articleId, version, elInstanceId, elName,
2880 defaultElLanguage);
2881
2882 Image defaultImage = imageLocalService.getImage(defaultImageId);
2883
2884 if (defaultImage != null) {
2885 dynamicContent.setText(elContent);
2886 dynamicContent.addAttribute(
2887 "id", String.valueOf(defaultImageId));
2888
2889 bytes = defaultImage.getTextObj();
2890
2891 imageLocalService.updateImage(defaultImageId, bytes);
2892
2893 continue;
2894 }
2895
2896 if (Validator.isNotNull(elLanguage)) {
2897 dynamicContent.setText(StringPool.BLANK);
2898 }
2899 }
2900 }
2901
2902 protected long getClassTypeId(JournalArticle article) {
2903 long classTypeId = 0;
2904
2905 try {
2906 JournalStructure structure = journalStructurePersistence.fetchByG_S(
2907 article.getGroupId(), article.getStructureId());
2908
2909 if (structure == null) {
2910 Group companyGroup = groupLocalService.getCompanyGroup(
2911 article.getCompanyId());
2912
2913 structure = journalStructurePersistence.fetchByG_S(
2914 companyGroup.getGroupId(), article.getStructureId());
2915 }
2916
2917 if (structure != null) {
2918 classTypeId = structure.getId();
2919 }
2920 }
2921 catch (Exception e) {
2922 _log.error(e, e);
2923 }
2924
2925 return classTypeId;
2926 }
2927
2928 protected Date[] getDateInterval(
2929 long groupId, String articleId, Date earliestDisplayDate,
2930 Date latestExpirationDate)
2931 throws SystemException {
2932
2933 Date[] dateInterval = new Date[2];
2934
2935 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2936 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2937
2938 boolean expiringArticle = true;
2939
2940 if (latestExpirationDate == null) {
2941 expiringArticle = false;
2942 }
2943
2944 for (JournalArticle article : articles) {
2945 if ((earliestDisplayDate == null) ||
2946 ((article.getDisplayDate() != null) &&
2947 earliestDisplayDate.after(article.getDisplayDate()))) {
2948
2949 earliestDisplayDate = article.getDisplayDate();
2950 }
2951
2952 if (expiringArticle &&
2953 ((latestExpirationDate == null) ||
2954 ((article.getExpirationDate() != null) &&
2955 latestExpirationDate.before(article.getExpirationDate())))) {
2956
2957 latestExpirationDate = article.getExpirationDate();
2958 }
2959
2960 if (expiringArticle && (article.getExpirationDate() == null) &&
2961 (latestExpirationDate != null)) {
2962
2963 expiringArticle = false;
2964 }
2965 }
2966
2967 dateInterval[0] = earliestDisplayDate;
2968 dateInterval[1] = latestExpirationDate;
2969
2970 return dateInterval;
2971 }
2972
2973 protected String getUniqueUrlTitle(
2974 long id, long groupId, String articleId, String title)
2975 throws PortalException, SystemException {
2976
2977 String urlTitle = JournalUtil.getUrlTitle(id, title);
2978
2979 String newUrlTitle = ModelHintsUtil.trimString(
2980 JournalArticle.class.getName(), "urlTitle", urlTitle);
2981
2982 for (int i = 1;; i++) {
2983 JournalArticle article = null;
2984
2985 try {
2986 article = getArticleByUrlTitle(groupId, newUrlTitle);
2987 }
2988 catch (NoSuchArticleException nsae) {
2989 }
2990
2991 if ((article == null) || article.getArticleId().equals(articleId)) {
2992 break;
2993 }
2994 else {
2995 String suffix = StringPool.DASH + i;
2996
2997 String prefix = newUrlTitle;
2998
2999 if (newUrlTitle.length() > suffix.length()) {
3000 prefix = newUrlTitle.substring(
3001 0, newUrlTitle.length() - suffix.length());
3002 }
3003
3004 newUrlTitle = prefix + suffix;
3005 }
3006 }
3007
3008 return newUrlTitle;
3009 }
3010
3011 protected void notifySubscribers(
3012 JournalArticle article, ServiceContext serviceContext)
3013 throws PortalException, SystemException {
3014
3015 if (!article.isApproved()) {
3016 return;
3017 }
3018
3019 String articleURL = PortalUtil.getControlPanelFullURL(
3020 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
3021
3022 if (Validator.isNull(articleURL)) {
3023 return;
3024 }
3025
3026 PortletPreferences preferences =
3027 ServiceContextUtil.getPortletPreferences(serviceContext);
3028
3029 if (preferences == null) {
3030 long ownerId = article.getGroupId();
3031 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
3032 long plid = PortletKeys.PREFS_PLID_SHARED;
3033 String portletId = PortletKeys.JOURNAL;
3034 String defaultPreferences = null;
3035
3036 preferences = portletPreferencesLocalService.getPreferences(
3037 article.getCompanyId(), ownerId, ownerType, plid, portletId,
3038 defaultPreferences);
3039 }
3040
3041 if ((article.getVersion() == 1.0) &&
3042 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
3043 }
3044 else if ((article.getVersion() != 1.0) &&
3045 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
3046 }
3047 else {
3048 return;
3049 }
3050
3051 String fromName = JournalUtil.getEmailFromName(
3052 preferences, article.getCompanyId());
3053 String fromAddress = JournalUtil.getEmailFromAddress(
3054 preferences, article.getCompanyId());
3055
3056 String subject = null;
3057 String body = null;
3058
3059 if (article.getVersion() == 1.0) {
3060 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
3061 body = JournalUtil.getEmailArticleAddedBody(preferences);
3062 }
3063 else {
3064 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
3065 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
3066 }
3067
3068 SubscriptionSender subscriptionSender = new SubscriptionSender();
3069
3070 subscriptionSender.setBody(body);
3071 subscriptionSender.setCompanyId(article.getCompanyId());
3072 subscriptionSender.setContextAttributes(
3073 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
3074 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
3075 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
3076 subscriptionSender.setContextUserPrefix("ARTICLE");
3077 subscriptionSender.setFrom(fromAddress, fromName);
3078 subscriptionSender.setHtmlFormat(true);
3079 subscriptionSender.setMailId("journal_article", article.getId());
3080 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
3081 subscriptionSender.setReplyToAddress(fromAddress);
3082 subscriptionSender.setScopeGroupId(article.getGroupId());
3083 subscriptionSender.setServiceContext(serviceContext);
3084 subscriptionSender.setSubject(subject);
3085 subscriptionSender.setUserId(article.getUserId());
3086
3087 subscriptionSender.addPersistedSubscribers(
3088 JournalArticle.class.getName(), article.getGroupId());
3089
3090 subscriptionSender.flushNotificationsAsync();
3091 }
3092
3093 protected void saveImages(
3094 boolean smallImage, long smallImageId, File smallImageFile,
3095 byte[] smallImageBytes)
3096 throws PortalException, SystemException {
3097
3098 if (smallImage) {
3099 if ((smallImageFile != null) && (smallImageBytes != null)) {
3100 imageLocalService.updateImage(smallImageId, smallImageBytes);
3101 }
3102 }
3103 else {
3104 imageLocalService.deleteImage(smallImageId);
3105 }
3106 }
3107
3108 protected void sendEmail(
3109 JournalArticle article, String articleURL,
3110 PortletPreferences preferences, String emailType,
3111 ServiceContext serviceContext)
3112 throws PortalException, SystemException {
3113
3114 if (preferences == null) {
3115 return;
3116 }
3117 else if (emailType.equals("denied") &&
3118 JournalUtil.getEmailArticleApprovalDeniedEnabled(preferences)) {
3119 }
3120 else if (emailType.equals("granted") &&
3121 JournalUtil.getEmailArticleApprovalGrantedEnabled(
3122 preferences)) {
3123 }
3124 else if (emailType.equals("requested") &&
3125 JournalUtil.getEmailArticleApprovalRequestedEnabled(
3126 preferences)) {
3127 }
3128 else if (emailType.equals("review") &&
3129 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
3130 }
3131 else {
3132 return;
3133 }
3134
3135 Company company = companyPersistence.findByPrimaryKey(
3136 article.getCompanyId());
3137
3138 User user = userPersistence.findByPrimaryKey(article.getUserId());
3139
3140 articleURL +=
3141 "&groupId=" + article.getGroupId() + "&articleId=" +
3142 article.getArticleId() + "&version=" + article.getVersion();
3143
3144 String fromName = JournalUtil.getEmailFromName(
3145 preferences, article.getCompanyId());
3146 String fromAddress = JournalUtil.getEmailFromAddress(
3147 preferences, article.getCompanyId());
3148
3149 String toName = user.getFullName();
3150 String toAddress = user.getEmailAddress();
3151
3152 if (emailType.equals("requested") ||
3153 emailType.equals("review")) {
3154
3155 String tempToName = fromName;
3156 String tempToAddress = fromAddress;
3157
3158 fromName = toName;
3159 fromAddress = toAddress;
3160
3161 toName = tempToName;
3162 toAddress = tempToAddress;
3163 }
3164
3165 String subject = null;
3166 String body = null;
3167
3168 if (emailType.equals("denied")) {
3169 subject =
3170 JournalUtil.getEmailArticleApprovalDeniedSubject(preferences);
3171 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
3172 }
3173 else if (emailType.equals("granted")) {
3174 subject =
3175 JournalUtil.getEmailArticleApprovalGrantedSubject(preferences);
3176 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
3177 }
3178 else if (emailType.equals("requested")) {
3179 subject =
3180 JournalUtil.getEmailArticleApprovalRequestedSubject(
3181 preferences);
3182 body = JournalUtil.getEmailArticleApprovalRequestedBody(
3183 preferences);
3184 }
3185 else if (emailType.equals("review")) {
3186 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
3187 body = JournalUtil.getEmailArticleReviewBody(preferences);
3188 }
3189
3190 SubscriptionSender subscriptionSender = new SubscriptionSender();
3191
3192 subscriptionSender.setBody(body);
3193 subscriptionSender.setCompanyId(company.getCompanyId());
3194 subscriptionSender.setContextAttributes(
3195 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
3196 article.getTitle(), "[$ARTICLE_URL$]", articleURL,
3197 "[$ARTICLE_USER_NAME$]", article.getUserName(),
3198 "[$ARTICLE_VERSION$]", article.getVersion());
3199 subscriptionSender.setContextUserPrefix("ARTICLE");
3200 subscriptionSender.setFrom(fromAddress, fromName);
3201 subscriptionSender.setHtmlFormat(true);
3202 subscriptionSender.setMailId("journal_article", article.getId());
3203 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
3204 subscriptionSender.setScopeGroupId(article.getGroupId());
3205 subscriptionSender.setServiceContext(serviceContext);
3206 subscriptionSender.setSubject(subject);
3207 subscriptionSender.setUserId(article.getUserId());
3208
3209 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
3210
3211 subscriptionSender.flushNotificationsAsync();
3212 }
3213
3214 protected void updatePreviousApprovedArticle(JournalArticle article)
3215 throws PortalException, SystemException {
3216
3217 List<JournalArticle> approvedArticles =
3218 journalArticlePersistence.findByG_A_ST(
3219 article.getGroupId(), article.getArticleId(),
3220 WorkflowConstants.STATUS_APPROVED, 0, 2);
3221
3222 if (approvedArticles.isEmpty() ||
3223 ((approvedArticles.size() == 1) &&
3224 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
3225
3226 if (article.isIndexable()) {
3227 Indexer indexer = IndexerRegistryUtil.getIndexer(
3228 JournalArticle.class);
3229
3230 indexer.delete(article);
3231 }
3232
3233 assetEntryLocalService.updateVisible(
3234 JournalArticle.class.getName(), article.getResourcePrimKey(),
3235 false);
3236 }
3237 else {
3238 JournalArticle previousApprovedArticle = approvedArticles.get(0);
3239
3240 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
3241 previousApprovedArticle = approvedArticles.get(1);
3242 }
3243
3244 if (article.isIndexable()) {
3245 Indexer indexer = IndexerRegistryUtil.getIndexer(
3246 JournalArticle.class);
3247
3248 indexer.reindex(previousApprovedArticle);
3249 }
3250 }
3251 }
3252
3253 protected void updateUrlTitles(
3254 long groupId, String articleId, String urlTitle)
3255 throws SystemException {
3256
3257 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3258 groupId, articleId);
3259
3260 for (JournalArticle article : articles) {
3261 if (!article.getUrlTitle().equals(urlTitle)) {
3262 article.setUrlTitle(urlTitle);
3263
3264 journalArticlePersistence.update(article, false);
3265 }
3266 }
3267 }
3268
3269 protected void validate(
3270 long companyId, long groupId, long classNameId,
3271 Map<Locale, String> titleMap, String content, String type,
3272 String structureId, String templateId, boolean smallImage,
3273 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
3274 throws PortalException, SystemException {
3275
3276 Locale defaultLocale = LocaleUtil.fromLanguageId(
3277 LocalizationUtil.getDefaultLocale(content));
3278
3279 if ((classNameId == 0) &&
3280 (titleMap.isEmpty() ||
3281 Validator.isNull(titleMap.get(defaultLocale)))) {
3282
3283 throw new ArticleTitleException();
3284 }
3285 else if (Validator.isNull(type)) {
3286 throw new ArticleTypeException();
3287 }
3288
3289 validateContent(content);
3290
3291 if (Validator.isNotNull(structureId)) {
3292 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
3293
3294 try {
3295 journalStructurePersistence.findByG_S(groupId, structureId);
3296 }
3297 catch (NoSuchStructureException nsse) {
3298 journalStructurePersistence.findByG_S(
3299 companyGroup.getGroupId(), structureId);
3300 }
3301
3302 JournalTemplate template = null;
3303
3304 if (Validator.isNotNull(templateId)) {
3305 try {
3306 template = journalTemplatePersistence.findByG_T(
3307 groupId, templateId);
3308 }
3309 catch (NoSuchTemplateException nste) {
3310 template = journalTemplatePersistence.findByG_T(
3311 companyGroup.getGroupId(), templateId);
3312 }
3313
3314 if (!template.getStructureId().equals(structureId)) {
3315 throw new NoSuchTemplateException();
3316 }
3317 }
3318 else if (classNameId == 0) {
3319 throw new NoSuchTemplateException();
3320 }
3321 }
3322
3323 String[] imageExtensions = PrefsPropsUtil.getStringArray(
3324 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
3325
3326 if (smallImage && Validator.isNull(smallImageURL) &&
3327 (smallImageFile != null) && (smallImageBytes != null)) {
3328
3329 String smallImageName = smallImageFile.getName();
3330
3331 if (smallImageName != null) {
3332 boolean validSmallImageExtension = false;
3333
3334 for (String _imageExtension : imageExtensions) {
3335 if (StringPool.STAR.equals(_imageExtension) ||
3336 StringUtil.endsWith(smallImageName, _imageExtension)) {
3337
3338 validSmallImageExtension = true;
3339
3340 break;
3341 }
3342 }
3343
3344 if (!validSmallImageExtension) {
3345 throw new ArticleSmallImageNameException(smallImageName);
3346 }
3347 }
3348
3349 long smallImageMaxSize = PrefsPropsUtil.getLong(
3350 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
3351
3352 if ((smallImageMaxSize > 0) &&
3353 ((smallImageBytes == null) ||
3354 (smallImageBytes.length > smallImageMaxSize))) {
3355
3356 throw new ArticleSmallImageSizeException();
3357 }
3358 }
3359 }
3360
3361 protected void validate(
3362 long companyId, long groupId, long classNameId, String articleId,
3363 boolean autoArticleId, double version, Map<Locale, String> titleMap,
3364 String content, String type, String structureId, String templateId,
3365 boolean smallImage, String smallImageURL, File smallImageFile,
3366 byte[] smallImageBytes)
3367 throws PortalException, SystemException {
3368
3369 if (!autoArticleId) {
3370 validate(groupId, articleId);
3371 }
3372
3373 validate(
3374 companyId, groupId, classNameId, titleMap, content, type,
3375 structureId, templateId, smallImage, smallImageURL, smallImageFile,
3376 smallImageBytes);
3377 }
3378
3379 protected void validate(long groupId, String articleId)
3380 throws PortalException, SystemException {
3381
3382 if ((Validator.isNull(articleId)) ||
3383 (articleId.indexOf(CharPool.SPACE) != -1)) {
3384
3385 throw new ArticleIdException();
3386 }
3387
3388 if (journalArticlePersistence.countByG_A(groupId, articleId) > 0) {
3389 throw new DuplicateArticleIdException();
3390 }
3391 }
3392
3393 protected void validateContent(String content) throws PortalException {
3394 if (Validator.isNull(content)) {
3395 throw new ArticleContentException();
3396 }
3397
3398 try {
3399 SAXReaderUtil.read(content);
3400 }
3401 catch (DocumentException de) {
3402 throw new ArticleContentException();
3403 }
3404 }
3405
3406 private static long _JOURNAL_ARTICLE_CHECK_INTERVAL =
3407 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
3408
3409 private static Log _log = LogFactoryUtil.getLog(
3410 JournalArticleLocalServiceImpl.class);
3411
3412 }