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