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