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