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