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.BooleanClauseOccur;
32 import com.liferay.portal.kernel.search.BooleanQuery;
33 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
34 import com.liferay.portal.kernel.search.Field;
35 import com.liferay.portal.kernel.search.Hits;
36 import com.liferay.portal.kernel.search.SearchEngineUtil;
37 import com.liferay.portal.kernel.search.SearchException;
38 import com.liferay.portal.kernel.search.Sort;
39 import com.liferay.portal.kernel.servlet.ImageServletTokenUtil;
40 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
41 import com.liferay.portal.kernel.util.ContentTypes;
42 import com.liferay.portal.kernel.util.FileUtil;
43 import com.liferay.portal.kernel.util.GetterUtil;
44 import com.liferay.portal.kernel.util.HtmlUtil;
45 import com.liferay.portal.kernel.util.HttpUtil;
46 import com.liferay.portal.kernel.util.ListUtil;
47 import com.liferay.portal.kernel.util.LocaleUtil;
48 import com.liferay.portal.kernel.util.MathUtil;
49 import com.liferay.portal.kernel.util.OrderByComparator;
50 import com.liferay.portal.kernel.util.StringPool;
51 import com.liferay.portal.kernel.util.StringUtil;
52 import com.liferay.portal.kernel.util.Validator;
53 import com.liferay.portal.kernel.xml.Document;
54 import com.liferay.portal.kernel.xml.DocumentException;
55 import com.liferay.portal.kernel.xml.Element;
56 import com.liferay.portal.kernel.xml.Node;
57 import com.liferay.portal.kernel.xml.SAXReaderUtil;
58 import com.liferay.portal.kernel.xml.XPath;
59 import com.liferay.portal.model.Company;
60 import com.liferay.portal.model.Image;
61 import com.liferay.portal.model.PortletPreferencesIds;
62 import com.liferay.portal.model.ResourceConstants;
63 import com.liferay.portal.model.User;
64 import com.liferay.portal.service.ServiceContext;
65 import com.liferay.portal.service.ServiceContextUtil;
66 import com.liferay.portal.servlet.filters.cache.CacheUtil;
67 import com.liferay.portal.theme.ThemeDisplay;
68 import com.liferay.portal.util.FriendlyURLNormalizer;
69 import com.liferay.portal.util.PortalUtil;
70 import com.liferay.portal.util.PortletKeys;
71 import com.liferay.portal.util.PrefsPropsUtil;
72 import com.liferay.portal.util.PropsKeys;
73 import com.liferay.portal.util.PropsUtil;
74 import com.liferay.portal.util.PropsValues;
75 import com.liferay.portlet.expando.model.ExpandoBridge;
76 import com.liferay.portlet.journal.ArticleContentException;
77 import com.liferay.portlet.journal.ArticleDisplayDateException;
78 import com.liferay.portlet.journal.ArticleExpirationDateException;
79 import com.liferay.portlet.journal.ArticleIdException;
80 import com.liferay.portlet.journal.ArticleReviewDateException;
81 import com.liferay.portlet.journal.ArticleSmallImageNameException;
82 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
83 import com.liferay.portlet.journal.ArticleTitleException;
84 import com.liferay.portlet.journal.ArticleTypeException;
85 import com.liferay.portlet.journal.DuplicateArticleIdException;
86 import com.liferay.portlet.journal.NoSuchArticleException;
87 import com.liferay.portlet.journal.NoSuchArticleResourceException;
88 import com.liferay.portlet.journal.NoSuchTemplateException;
89 import com.liferay.portlet.journal.StructureXsdException;
90 import com.liferay.portlet.journal.job.CheckArticleJob;
91 import com.liferay.portlet.journal.model.JournalArticle;
92 import com.liferay.portlet.journal.model.JournalArticleDisplay;
93 import com.liferay.portlet.journal.model.JournalStructure;
94 import com.liferay.portlet.journal.model.JournalTemplate;
95 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
96 import com.liferay.portlet.journal.model.impl.JournalArticleImpl;
97 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
98 import com.liferay.portlet.journal.util.Indexer;
99 import com.liferay.portlet.journal.util.JournalUtil;
100 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
101 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
102 import com.liferay.portlet.tags.model.TagsEntry;
103 import com.liferay.portlet.tags.model.TagsEntryConstants;
104 import com.liferay.util.LocalizationUtil;
105
106 import java.io.File;
107 import java.io.IOException;
108
109 import java.util.Calendar;
110 import java.util.Date;
111 import java.util.HashSet;
112 import java.util.List;
113 import java.util.Map;
114 import java.util.Set;
115
116 import javax.mail.internet.InternetAddress;
117
118 import javax.portlet.PortletPreferences;
119
120
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 List<JournalArticle> articles = journalArticlePersistence.findByG_UT(
905 groupId, urlTitle, 0, 1);
906
907 if (articles.size() == 0) {
908 throw new NoSuchArticleException();
909 }
910
911 return articles.get(0);
912 }
913
914 public String getArticleContent(
915 long groupId, String articleId, String viewMode, String languageId,
916 ThemeDisplay themeDisplay)
917 throws PortalException, SystemException {
918
919 return getArticleContent(
920 groupId, articleId, viewMode, null, languageId, themeDisplay);
921 }
922
923 public String getArticleContent(
924 long groupId, String articleId, String viewMode, String templateId,
925 String languageId, ThemeDisplay themeDisplay)
926 throws PortalException, SystemException {
927
928 JournalArticleDisplay articleDisplay = getArticleDisplay(
929 groupId, articleId, templateId, viewMode, languageId, themeDisplay);
930
931 return articleDisplay.getContent();
932 }
933
934 public String getArticleContent(
935 long groupId, String articleId, double version, String viewMode,
936 String languageId, ThemeDisplay themeDisplay)
937 throws PortalException, SystemException {
938
939 return getArticleContent(
940 groupId, articleId, version, viewMode, null, languageId,
941 themeDisplay);
942 }
943
944 public String getArticleContent(
945 long groupId, String articleId, double version, String viewMode,
946 String templateId, String languageId, ThemeDisplay themeDisplay)
947 throws PortalException, SystemException {
948
949 JournalArticleDisplay articleDisplay = getArticleDisplay(
950 groupId, articleId, version, templateId, viewMode, languageId,
951 themeDisplay);
952
953 if (articleDisplay == null) {
954 return StringPool.BLANK;
955 }
956 else {
957 return articleDisplay.getContent();
958 }
959 }
960
961 public String getArticleContent(
962 JournalArticle article, String templateId, String viewMode,
963 String languageId, ThemeDisplay themeDisplay)
964 throws SystemException {
965
966 JournalArticleDisplay articleDisplay = getArticleDisplay(
967 article, templateId, viewMode, languageId, 1, null, themeDisplay);
968
969 if (articleDisplay == null) {
970 return StringPool.BLANK;
971 }
972 else {
973 return articleDisplay.getContent();
974 }
975 }
976
977 public JournalArticleDisplay getArticleDisplay(
978 long groupId, String articleId, String viewMode, String languageId,
979 ThemeDisplay themeDisplay)
980 throws PortalException, SystemException {
981
982 return getArticleDisplay(
983 groupId, articleId, null, viewMode, languageId, themeDisplay);
984 }
985
986 public JournalArticleDisplay getArticleDisplay(
987 long groupId, String articleId, String viewMode, String languageId,
988 int page, String xmlRequest, ThemeDisplay themeDisplay)
989 throws PortalException, SystemException {
990
991 return getArticleDisplay(
992 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
993 themeDisplay);
994 }
995
996 public JournalArticleDisplay getArticleDisplay(
997 long groupId, String articleId, String templateId, String viewMode,
998 String languageId, ThemeDisplay themeDisplay)
999 throws PortalException, SystemException {
1000
1001 JournalArticle article = getDisplayArticle(groupId, articleId);
1002
1003 return getArticleDisplay(
1004 groupId, articleId, article.getVersion(), templateId, viewMode,
1005 languageId, themeDisplay);
1006 }
1007
1008 public JournalArticleDisplay getArticleDisplay(
1009 long groupId, String articleId, String templateId, String viewMode,
1010 String languageId, int page, String xmlRequest,
1011 ThemeDisplay themeDisplay)
1012 throws PortalException, SystemException {
1013
1014 JournalArticle article = getDisplayArticle(groupId, articleId);
1015
1016 return getArticleDisplay(
1017 groupId, articleId, article.getVersion(), templateId, viewMode,
1018 languageId, page, xmlRequest, themeDisplay);
1019 }
1020
1021 public JournalArticleDisplay getArticleDisplay(
1022 long groupId, String articleId, double version, String templateId,
1023 String viewMode, String languageId, ThemeDisplay themeDisplay)
1024 throws PortalException, SystemException {
1025
1026 return getArticleDisplay(
1027 groupId, articleId, version, templateId, viewMode, languageId, 1,
1028 null, themeDisplay);
1029 }
1030
1031 public JournalArticleDisplay getArticleDisplay(
1032 long groupId, String articleId, double version, String templateId,
1033 String viewMode, String languageId, int page, String xmlRequest,
1034 ThemeDisplay themeDisplay)
1035 throws PortalException, SystemException {
1036
1037 Date now = new Date();
1038
1039 JournalArticle article = journalArticlePersistence.findByG_A_V(
1040 groupId, articleId, version);
1041
1042 if (article.isExpired()) {
1043 Date expirationDate = article.getExpirationDate();
1044
1045 if ((expirationDate != null) && expirationDate.before(now)) {
1046 return null;
1047 }
1048 }
1049
1050 if (article.getDisplayDate().after(now)) {
1051 return null;
1052 }
1053
1054 return getArticleDisplay(
1055 article, templateId, viewMode, languageId, page, xmlRequest,
1056 themeDisplay);
1057 }
1058
1059 public JournalArticleDisplay getArticleDisplay(
1060 JournalArticle article, String templateId, String viewMode,
1061 String languageId, int page, String xmlRequest,
1062 ThemeDisplay themeDisplay)
1063 throws SystemException {
1064
1065 String content = null;
1066
1067 if (page < 1) {
1068 page = 1;
1069 }
1070
1071 int numberOfPages = 1;
1072 boolean paginate = false;
1073 boolean pageFlow = false;
1074
1075 boolean cacheable = true;
1076
1077 if (Validator.isNull(xmlRequest)) {
1078 xmlRequest = "<request />";
1079 }
1080
1081 Map<String, String> tokens = JournalUtil.getTokens(
1082 article.getGroupId(), themeDisplay, xmlRequest);
1083
1084 tokens.put(
1085 "article_resource_pk",
1086 String.valueOf(article.getResourcePrimKey()));
1087
1088 String defaultTemplateId = article.getTemplateId();
1089
1090 if (article.isTemplateDriven()) {
1091 if (Validator.isNull(templateId)) {
1092 templateId = defaultTemplateId;
1093 }
1094
1095 tokens.put("structure_id", article.getStructureId());
1096 tokens.put("template_id", templateId);
1097 }
1098
1099 String xml = article.getContent();
1100
1101 try {
1102 Document doc = null;
1103
1104 Element root = null;
1105
1106 if (article.isTemplateDriven()) {
1107 doc = SAXReaderUtil.read(xml);
1108
1109 root = doc.getRootElement();
1110
1111 Document request = SAXReaderUtil.read(xmlRequest);
1112
1113 List<Element> pages = root.elements("page");
1114
1115 if (pages.size() > 0) {
1116 pageFlow = true;
1117
1118 String targetPage = request.valueOf(
1119 "/request/parameters/parameter[name='targetPage']/" +
1120 "value");
1121
1122 Element pageEl = null;
1123
1124 if (Validator.isNotNull(targetPage)) {
1125 XPath xpathSelector = SAXReaderUtil.createXPath(
1126 "/root/page[@id = '" + targetPage + "']");
1127
1128 pageEl = (Element)xpathSelector.selectSingleNode(doc);
1129 }
1130
1131 if (pageEl != null) {
1132 doc = SAXReaderUtil.createDocument(pageEl);
1133
1134 root = doc.getRootElement();
1135
1136 numberOfPages = pages.size();
1137 }
1138 else {
1139 if (page > pages.size()) {
1140 page = 1;
1141 }
1142
1143 pageEl = pages.get(page - 1);
1144
1145 doc = SAXReaderUtil.createDocument(pageEl);
1146
1147 root = doc.getRootElement();
1148
1149 numberOfPages = pages.size();
1150 paginate = true;
1151 }
1152 }
1153
1154 root.add(request.getRootElement().createCopy());
1155
1156 JournalUtil.addAllReservedEls(root, tokens, article);
1157
1158 xml = JournalUtil.formatXML(doc);
1159 }
1160 }
1161 catch (DocumentException de) {
1162 throw new SystemException(de);
1163 }
1164 catch (IOException ioe) {
1165 throw new SystemException(ioe);
1166 }
1167
1168 try {
1169 if (_log.isDebugEnabled()) {
1170 _log.debug(
1171 "Transforming " + article.getArticleId() + " " +
1172 article.getVersion() + " " + languageId);
1173 }
1174
1175 String script = null;
1176 String langType = null;
1177
1178 if (article.isTemplateDriven()) {
1179
1180
1185 JournalTemplate template = null;
1186
1187 try {
1188 template = journalTemplatePersistence.findByG_T(
1189 article.getGroupId(), templateId);
1190 }
1191 catch (NoSuchTemplateException nste) {
1192 if (!defaultTemplateId.equals(templateId)) {
1193 template = journalTemplatePersistence.findByG_T(
1194 article.getGroupId(), defaultTemplateId);
1195 }
1196 else {
1197 throw nste;
1198 }
1199 }
1200
1201 script = template.getXsl();
1202 langType = template.getLangType();
1203 cacheable = template.isCacheable();
1204 }
1205
1206 content = JournalUtil.transform(
1207 tokens, viewMode, languageId, xml, script, langType);
1208
1209 if (!pageFlow) {
1210 String[] pieces = StringUtil.split(content, _TOKEN_PAGE_BREAK);
1211
1212 if (pieces.length > 1) {
1213 if (page > pieces.length) {
1214 page = 1;
1215 }
1216
1217 content = pieces[page - 1];
1218 numberOfPages = pieces.length;
1219 paginate = true;
1220 }
1221 }
1222 }
1223 catch (Exception e) {
1224 throw new SystemException(e);
1225 }
1226
1227 return new JournalArticleDisplayImpl(
1228 article.getId(), article.getResourcePrimKey(), article.getGroupId(),
1229 article.getUserId(), article.getArticleId(), article.getVersion(),
1230 article.getTitle(), article.getUrlTitle(), article.getDescription(),
1231 article.getAvailableLocales(), content, article.getType(),
1232 article.getStructureId(), templateId, article.isSmallImage(),
1233 article.getSmallImageId(), article.getSmallImageURL(),
1234 numberOfPages, page, paginate, cacheable);
1235 }
1236
1237 public List<JournalArticle> getArticles() throws SystemException {
1238 return journalArticlePersistence.findAll();
1239 }
1240
1241 public List<JournalArticle> getArticles(long groupId)
1242 throws SystemException {
1243
1244 return journalArticlePersistence.findByGroupId(groupId);
1245 }
1246
1247 public List<JournalArticle> getArticles(long groupId, int start, int end)
1248 throws SystemException {
1249
1250 return journalArticlePersistence.findByGroupId(groupId, start, end);
1251 }
1252
1253 public List<JournalArticle> getArticles(
1254 long groupId, int start, int end, OrderByComparator obc)
1255 throws SystemException {
1256
1257 return journalArticlePersistence.findByGroupId(
1258 groupId, start, end, obc);
1259 }
1260
1261 public List<JournalArticle> getArticles(long groupId, String articleId)
1262 throws SystemException {
1263
1264 return journalArticlePersistence.findByG_A(groupId, articleId);
1265 }
1266
1267 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
1268 throws SystemException {
1269
1270 return journalArticlePersistence.findBySmallImageId(smallImageId);
1271 }
1272
1273 public int getArticlesCount(long groupId) throws SystemException {
1274 return journalArticlePersistence.countByGroupId(groupId);
1275 }
1276
1277 public JournalArticle getDisplayArticle(long groupId, String articleId)
1278 throws PortalException, SystemException {
1279
1280 List<JournalArticle> articles = journalArticlePersistence.findByG_A_A(
1281 groupId, articleId, true);
1282
1283 if (articles.size() == 0) {
1284 throw new NoSuchArticleException();
1285 }
1286
1287 Date now = new Date();
1288
1289 for (int i = 0; i < articles.size(); i++) {
1290 JournalArticle article = articles.get(i);
1291
1292 Date expirationDate = article.getExpirationDate();
1293
1294 if (article.getDisplayDate().before(now) &&
1295 ((expirationDate == null) || expirationDate.after(now))) {
1296
1297 return article;
1298 }
1299 }
1300
1301 return articles.get(0);
1302 }
1303
1304 public JournalArticle getLatestArticle(long resourcePrimKey)
1305 throws PortalException, SystemException {
1306
1307 return getLatestArticle(resourcePrimKey, (Boolean)null);
1308 }
1309
1310 public JournalArticle getLatestArticle(
1311 long resourcePrimKey, Boolean approved)
1312 throws PortalException, SystemException {
1313
1314 List<JournalArticle> articles = null;
1315
1316 OrderByComparator orderByComparator = new ArticleVersionComparator();
1317
1318 if (approved == null) {
1319 articles = journalArticlePersistence.findByR_A(
1320 resourcePrimKey, true, 0, 1, orderByComparator);
1321
1322 if (articles.size() == 0) {
1323 articles = journalArticlePersistence.findByR_A(
1324 resourcePrimKey, false, 0, 1, orderByComparator);
1325 }
1326 }
1327 else {
1328 articles = journalArticlePersistence.findByR_A(
1329 resourcePrimKey, approved.booleanValue(), 0, 1,
1330 orderByComparator);
1331 }
1332
1333 if (articles.size() == 0) {
1334 throw new NoSuchArticleException();
1335 }
1336
1337 return articles.get(0);
1338 }
1339
1340 public JournalArticle getLatestArticle(long groupId, String articleId)
1341 throws PortalException, SystemException {
1342
1343 return getLatestArticle(groupId, articleId, null);
1344 }
1345
1346 public JournalArticle getLatestArticle(
1347 long groupId, String articleId, Boolean approved)
1348 throws PortalException, SystemException {
1349
1350 List<JournalArticle> articles = null;
1351
1352 if (approved == null) {
1353 articles = journalArticlePersistence.findByG_A(
1354 groupId, articleId, 0, 1);
1355 }
1356 else {
1357 articles = journalArticlePersistence.findByG_A_A(
1358 groupId, articleId, approved.booleanValue(), 0, 1);
1359 }
1360
1361 if (articles.size() == 0) {
1362 throw new NoSuchArticleException();
1363 }
1364
1365 return articles.get(0);
1366 }
1367
1368 public double getLatestVersion(long groupId, String articleId)
1369 throws PortalException, SystemException {
1370
1371 JournalArticle article = getLatestArticle(groupId, articleId);
1372
1373 return article.getVersion();
1374 }
1375
1376 public double getLatestVersion(
1377 long groupId, String articleId, Boolean approved)
1378 throws PortalException, SystemException {
1379
1380 JournalArticle article = getLatestArticle(groupId, articleId, approved);
1381
1382 return article.getVersion();
1383 }
1384
1385 public List<JournalArticle> getStructureArticles(
1386 long groupId, String structureId)
1387 throws SystemException {
1388
1389 return journalArticlePersistence.findByG_S(groupId, structureId);
1390 }
1391
1392 public List<JournalArticle> getStructureArticles(
1393 long groupId, String structureId, int start, int end,
1394 OrderByComparator obc)
1395 throws SystemException {
1396
1397 return journalArticlePersistence.findByG_S(
1398 groupId, structureId, start, end, obc);
1399 }
1400
1401 public int getStructureArticlesCount(long groupId, String structureId)
1402 throws SystemException {
1403
1404 return journalArticlePersistence.countByG_S(groupId, structureId);
1405 }
1406
1407 public List<JournalArticle> getTemplateArticles(
1408 long groupId, String templateId)
1409 throws SystemException {
1410
1411 return journalArticlePersistence.findByG_T(groupId, templateId);
1412 }
1413
1414 public List<JournalArticle> getTemplateArticles(
1415 long groupId, String templateId, int start, int end,
1416 OrderByComparator obc)
1417 throws SystemException {
1418
1419 return journalArticlePersistence.findByG_T(
1420 groupId, templateId, start, end, obc);
1421 }
1422
1423 public int getTemplateArticlesCount(long groupId, String templateId)
1424 throws SystemException {
1425
1426 return journalArticlePersistence.countByG_T(groupId, templateId);
1427 }
1428
1429 public boolean hasArticle(long groupId, String articleId)
1430 throws SystemException {
1431
1432 try {
1433 getArticle(groupId, articleId);
1434
1435 return true;
1436 }
1437 catch (PortalException pe) {
1438 return false;
1439 }
1440 }
1441
1442 public boolean isLatestVersion(
1443 long groupId, String articleId, double version)
1444 throws PortalException, SystemException {
1445
1446 if (getLatestVersion(groupId, articleId) == version) {
1447 return true;
1448 }
1449 else {
1450 return false;
1451 }
1452 }
1453
1454 public boolean isLatestVersion(
1455 long groupId, String articleId, double version, Boolean active)
1456 throws PortalException, SystemException {
1457
1458 if (getLatestVersion(groupId, articleId, active) == version) {
1459 return true;
1460 }
1461 else {
1462 return false;
1463 }
1464 }
1465
1466 public void reIndex(long resourcePrimKey) throws SystemException {
1467 if (SearchEngineUtil.isIndexReadOnly()) {
1468 return;
1469 }
1470
1471 JournalArticle article = null;
1472
1473 try {
1474 article = getLatestArticle(resourcePrimKey, Boolean.TRUE);
1475 }
1476 catch (Exception e) {
1477 if (e instanceof NoSuchArticleException) {
1478 return;
1479 }
1480 }
1481
1482 reIndex(article);
1483 }
1484
1485 public void reIndex(JournalArticle article) throws SystemException {
1486 if (!article.isApproved() || !article.isIndexable()) {
1487 return;
1488 }
1489
1490 long companyId = article.getCompanyId();
1491 long groupId = article.getGroupId();
1492 long resourcePrimKey = article.getResourcePrimKey();
1493 String articleId = article.getArticleId();
1494 double version = article.getVersion();
1495 String title = article.getTitle();
1496 String description = article.getDescription();
1497 String content = article.getContent();
1498 String type = article.getType();
1499 Date displayDate = article.getDisplayDate();
1500
1501 String[] tagsCategories = tagsEntryLocalService.getEntryNames(
1502 JournalArticle.class.getName(), resourcePrimKey,
1503 TagsEntryConstants.FOLKSONOMY_CATEGORY);
1504 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
1505 JournalArticle.class.getName(), resourcePrimKey);
1506
1507 ExpandoBridge expandoBridge = article.getExpandoBridge();
1508
1509 try {
1510 Indexer.updateArticle(
1511 companyId, groupId, articleId, version, title, description,
1512 content, type, displayDate, tagsCategories, tagsEntries,
1513 expandoBridge);
1514 }
1515 catch (SearchException se) {
1516 _log.error("Reindexing " + article.getId(), se);
1517 }
1518 }
1519
1520 public void reIndex(String[] ids) throws SystemException {
1521 if (SearchEngineUtil.isIndexReadOnly()) {
1522 return;
1523 }
1524
1525 long companyId = GetterUtil.getLong(ids[0]);
1526
1527 try {
1528 reIndexArticles(companyId);
1529 }
1530 catch (SystemException se) {
1531 throw se;
1532 }
1533 catch (Exception e) {
1534 throw new SystemException(e);
1535 }
1536 }
1537
1538 public JournalArticle removeArticleLocale(
1539 long groupId, String articleId, double version, String languageId)
1540 throws PortalException, SystemException {
1541
1542 JournalArticle article = journalArticlePersistence.findByG_A_V(
1543 groupId, articleId, version);
1544
1545 String content = article.getContent();
1546
1547 if (article.isTemplateDriven()) {
1548 content = JournalUtil.removeArticleLocale(content, languageId);
1549 }
1550 else {
1551 content = LocalizationUtil.removeLocalization(
1552 content, "static-content", languageId, true);
1553 }
1554
1555 article.setContent(content);
1556
1557 journalArticlePersistence.update(article, false);
1558
1559 return article;
1560 }
1561
1562 public Hits search(
1563 long companyId, long groupId, String keywords, int start, int end)
1564 throws SystemException {
1565
1566 Sort sort = new Sort("displayDate", Sort.LONG_TYPE, true);
1567
1568 return search(companyId, groupId, keywords, sort, start, end);
1569 }
1570
1571 public Hits search(
1572 long companyId, long groupId, String keywords, Sort sort, int start,
1573 int end)
1574 throws SystemException {
1575
1576 return search(
1577 companyId, groupId, keywords, new Sort[] {sort}, start, end);
1578 }
1579
1580 public Hits search(
1581 long companyId, long groupId, String keywords, Sort[] sorts,
1582 int start, int end)
1583 throws SystemException {
1584
1585 try {
1586 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
1587
1588 contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
1589
1590 if (groupId > 0) {
1591 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
1592 }
1593
1594 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
1595
1596 if (Validator.isNotNull(keywords)) {
1597 searchQuery.addTerm(Field.TITLE, keywords);
1598 searchQuery.addTerm(Field.CONTENT, keywords);
1599 searchQuery.addTerm(Field.DESCRIPTION, keywords);
1600 searchQuery.addTerm(Field.TAGS_CATEGORIES, keywords);
1601 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords, true);
1602 searchQuery.addTerm(Field.TYPE, keywords);
1603 }
1604
1605 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
1606
1607 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
1608
1609 if (searchQuery.clauses().size() > 0) {
1610 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
1611 }
1612
1613 return SearchEngineUtil.search(
1614 companyId, fullQuery, sorts, start, end);
1615 }
1616 catch (Exception e) {
1617 throw new SystemException(e);
1618 }
1619 }
1620
1621 public List<JournalArticle> search(
1622 long companyId, long groupId, String keywords, Double version,
1623 String type, String structureId, String templateId,
1624 Date displayDateGT, Date displayDateLT, Boolean approved,
1625 Boolean expired, Date reviewDate, int start, int end,
1626 OrderByComparator obc)
1627 throws SystemException {
1628
1629 return journalArticleFinder.findByKeywords(
1630 companyId, groupId, keywords, version, type, structureId,
1631 templateId, displayDateGT, displayDateLT, approved, expired,
1632 reviewDate, start, end, obc);
1633 }
1634
1635 public List<JournalArticle> search(
1636 long companyId, long groupId, String articleId, Double version,
1637 String title, String description, String content, String type,
1638 String structureId, String templateId, Date displayDateGT,
1639 Date displayDateLT, Boolean approved, Boolean expired,
1640 Date reviewDate, boolean andOperator, int start, int end,
1641 OrderByComparator obc)
1642 throws SystemException {
1643
1644 return journalArticleFinder.findByC_G_A_V_T_D_C_T_S_T_D_A_E_R(
1645 companyId, groupId, articleId, version, title, description, content,
1646 type, structureId, templateId, displayDateGT, displayDateLT,
1647 approved, expired, reviewDate, andOperator, start, end, obc);
1648 }
1649
1650 public List<JournalArticle> search(
1651 long companyId, long groupId, String articleId, Double version,
1652 String title, String description, String content, String type,
1653 String[] structureIds, String[] templateIds, Date displayDateGT,
1654 Date displayDateLT, Boolean approved, Boolean expired,
1655 Date reviewDate, boolean andOperator, int start, int end,
1656 OrderByComparator obc)
1657 throws SystemException {
1658
1659 return journalArticleFinder.findByC_G_A_V_T_D_C_T_S_T_D_A_E_R(
1660 companyId, groupId, articleId, version, title, description, content,
1661 type, structureIds, templateIds, displayDateGT, displayDateLT,
1662 approved, expired, reviewDate, andOperator, start, end, obc);
1663 }
1664
1665 public int searchCount(
1666 long companyId, long groupId, String keywords, Double version,
1667 String type, String structureId, String templateId,
1668 Date displayDateGT, Date displayDateLT, Boolean approved,
1669 Boolean expired, Date reviewDate)
1670 throws SystemException {
1671
1672 return journalArticleFinder.countByKeywords(
1673 companyId, groupId, keywords, version, type, structureId,
1674 templateId, displayDateGT, displayDateLT, approved, expired,
1675 reviewDate);
1676 }
1677
1678 public int searchCount(
1679 long companyId, long groupId, String articleId, Double version,
1680 String title, String description, String content, String type,
1681 String structureId, String templateId, Date displayDateGT,
1682 Date displayDateLT, Boolean approved, Boolean expired,
1683 Date reviewDate, boolean andOperator)
1684 throws SystemException {
1685
1686 return journalArticleFinder.countByC_G_A_V_T_D_C_T_S_T_D_A_E_R(
1687 companyId, groupId, articleId, version, title, description, content,
1688 type, structureId, templateId, displayDateGT, displayDateLT,
1689 approved, expired, reviewDate, andOperator);
1690 }
1691
1692 public int searchCount(
1693 long companyId, long groupId, String articleId, Double version,
1694 String title, String description, String content, String type,
1695 String[] structureIds, String[] templateIds, Date displayDateGT,
1696 Date displayDateLT, Boolean approved, Boolean expired,
1697 Date reviewDate, boolean andOperator)
1698 throws SystemException {
1699
1700 return journalArticleFinder.countByC_G_A_V_T_D_C_T_S_T_D_A_E_R(
1701 companyId, groupId, articleId, version, title, description, content,
1702 type, structureIds, templateIds, displayDateGT, displayDateLT,
1703 approved, expired, reviewDate, andOperator);
1704 }
1705
1706 public JournalArticle updateArticle(
1707 long userId, long groupId, String articleId, double version,
1708 boolean incrementVersion, String content)
1709 throws PortalException, SystemException {
1710
1711 User user = userPersistence.findByPrimaryKey(userId);
1712
1713 JournalArticle article = journalArticlePersistence.findByG_A_V(
1714 groupId, articleId, version);
1715
1716 Date displayDate = article.getDisplayDate();
1717
1718 int displayDateMonth = 0;
1719 int displayDateDay = 0;
1720 int displayDateYear = 0;
1721 int displayDateHour = 0;
1722 int displayDateMinute = 0;
1723
1724 if (displayDate != null) {
1725 Calendar displayCal = CalendarFactoryUtil.getCalendar(
1726 user.getTimeZone());
1727
1728 displayCal.setTime(displayDate);
1729
1730 displayDateMonth = displayCal.get(Calendar.MONTH);
1731 displayDateDay = displayCal.get(Calendar.DATE);
1732 displayDateYear = displayCal.get(Calendar.YEAR);
1733 displayDateHour = displayCal.get(Calendar.HOUR);
1734 displayDateMinute = displayCal.get(Calendar.MINUTE);
1735
1736 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
1737 displayDateHour += 12;
1738 }
1739 }
1740
1741 Date expirationDate = article.getExpirationDate();
1742
1743 int expirationDateMonth = 0;
1744 int expirationDateDay = 0;
1745 int expirationDateYear = 0;
1746 int expirationDateHour = 0;
1747 int expirationDateMinute = 0;
1748 boolean neverExpire = true;
1749
1750 if (expirationDate != null) {
1751 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
1752 user.getTimeZone());
1753
1754 expirationCal.setTime(expirationDate);
1755
1756 expirationDateMonth = expirationCal.get(Calendar.MONTH);
1757 expirationDateDay = expirationCal.get(Calendar.DATE);
1758 expirationDateYear = expirationCal.get(Calendar.YEAR);
1759 expirationDateHour = expirationCal.get(Calendar.HOUR);
1760 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
1761 neverExpire = false;
1762
1763 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
1764 expirationDateHour += 12;
1765 }
1766 }
1767
1768 Date reviewDate = article.getReviewDate();
1769
1770 int reviewDateMonth = 0;
1771 int reviewDateDay = 0;
1772 int reviewDateYear = 0;
1773 int reviewDateHour = 0;
1774 int reviewDateMinute = 0;
1775 boolean neverReview = true;
1776
1777 if (reviewDate != null) {
1778 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
1779 user.getTimeZone());
1780
1781 reviewCal.setTime(reviewDate);
1782
1783 reviewDateMonth = reviewCal.get(Calendar.MONTH);
1784 reviewDateDay = reviewCal.get(Calendar.DATE);
1785 reviewDateYear = reviewCal.get(Calendar.YEAR);
1786 reviewDateHour = reviewCal.get(Calendar.HOUR);
1787 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
1788 neverReview = false;
1789
1790 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
1791 reviewDateHour += 12;
1792 }
1793 }
1794
1795 PortletPreferencesIds portletPreferencesIds = new PortletPreferencesIds(
1796 article.getCompanyId(), PortletKeys.PREFS_OWNER_ID_DEFAULT,
1797 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, PortletKeys.PREFS_PLID_SHARED,
1798 PortletKeys.JOURNAL);
1799
1800 String[] tagsCategories = getTagsEntries(article);
1801 String[] tagsEntries = getTagsCategories(article);
1802
1803 ServiceContext serviceContext = new ServiceContext();
1804
1805 serviceContext.setPortletPreferencesIds(portletPreferencesIds);
1806 serviceContext.setTagsCategories(tagsCategories);
1807 serviceContext.setTagsEntries(tagsEntries);
1808
1809 return updateArticle(
1810 userId, groupId, articleId, version, incrementVersion,
1811 article.getTitle(), article.getDescription(), content,
1812 article.getType(), article.getStructureId(),
1813 article.getTemplateId(), displayDateMonth, displayDateDay,
1814 displayDateYear, displayDateHour, displayDateMinute,
1815 expirationDateMonth, expirationDateDay, expirationDateYear,
1816 expirationDateHour, expirationDateMinute, neverExpire,
1817 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
1818 reviewDateMinute, neverReview, article.getIndexable(),
1819 article.isSmallImage(), article.getSmallImageURL(), null, null,
1820 null, serviceContext);
1821 }
1822
1823 public JournalArticle updateArticle(
1824 long userId, long groupId, String articleId, double version,
1825 boolean incrementVersion, String title, String description,
1826 String content, String type, String structureId, String templateId,
1827 int displayDateMonth, int displayDateDay, int displayDateYear,
1828 int displayDateHour, int displayDateMinute, int expirationDateMonth,
1829 int expirationDateDay, int expirationDateYear,
1830 int expirationDateHour, int expirationDateMinute,
1831 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
1832 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
1833 boolean neverReview, boolean indexable, boolean smallImage,
1834 String smallImageURL, File smallFile, Map<String, byte[]> images,
1835 String articleURL, ServiceContext serviceContext)
1836 throws PortalException, SystemException {
1837
1838
1840 User user = userPersistence.findByPrimaryKey(userId);
1841 articleId = articleId.trim().toUpperCase();
1842
1843 Date displayDate = PortalUtil.getDate(
1844 displayDateMonth, displayDateDay, displayDateYear,
1845 displayDateHour, displayDateMinute, user.getTimeZone(),
1846 new ArticleDisplayDateException());
1847
1848 Date expirationDate = null;
1849
1850 if (!neverExpire) {
1851 expirationDate = PortalUtil.getDate(
1852 expirationDateMonth, expirationDateDay, expirationDateYear,
1853 expirationDateHour, expirationDateMinute, user.getTimeZone(),
1854 new ArticleExpirationDateException());
1855 }
1856
1857 Date reviewDate = null;
1858
1859 if (!neverReview) {
1860 reviewDate = PortalUtil.getDate(
1861 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
1862 reviewDateMinute, user.getTimeZone(),
1863 new ArticleReviewDateException());
1864 }
1865
1866 byte[] smallBytes = null;
1867
1868 try {
1869 smallBytes = FileUtil.getBytes(smallFile);
1870 }
1871 catch (IOException ioe) {
1872 }
1873
1874 Date now = new Date();
1875
1876 validate(
1877 groupId, title, content, type, structureId, templateId, smallImage,
1878 smallImageURL, smallFile, smallBytes);
1879
1880 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
1881 groupId, articleId, version);
1882
1883 JournalArticle article = null;
1884
1885 if (incrementVersion) {
1886 double latestVersion = getLatestVersion(groupId, articleId);
1887
1888 long id = counterLocalService.increment();
1889
1890 article = journalArticlePersistence.create(id);
1891
1892 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
1893 article.setGroupId(oldArticle.getGroupId());
1894 article.setCompanyId(user.getCompanyId());
1895 article.setUserId(user.getUserId());
1896 article.setUserName(user.getFullName());
1897 article.setCreateDate(now);
1898 article.setArticleId(articleId);
1899 article.setVersion(MathUtil.format(latestVersion + 0.1, 1, 1));
1900 article.setSmallImageId(oldArticle.getSmallImageId());
1901 }
1902 else {
1903 article = oldArticle;
1904 }
1905
1906 content = format(
1907 groupId, articleId, article.getVersion(), incrementVersion, content,
1908 structureId, images);
1909
1910 boolean approved = oldArticle.isApproved();
1911
1912 if (incrementVersion) {
1913 approved = false;
1914 }
1915
1916 article.setModifiedDate(now);
1917 article.setTitle(title);
1918 article.setUrlTitle(
1919 getUniqueUrlTitle(article.getId(), groupId, articleId, title));
1920 article.setDescription(description);
1921 article.setContent(content);
1922 article.setType(type);
1923 article.setStructureId(structureId);
1924 article.setTemplateId(templateId);
1925 article.setDisplayDate(displayDate);
1926 article.setApproved(approved);
1927
1928 if ((expirationDate == null) || expirationDate.after(now)) {
1929 article.setExpired(false);
1930 }
1931 else {
1932 article.setExpired(true);
1933 }
1934
1935 article.setExpirationDate(expirationDate);
1936 article.setReviewDate(reviewDate);
1937 article.setIndexable(indexable);
1938 article.setSmallImage(smallImage);
1939
1940 if (article.getSmallImageId() == 0) {
1941 article.setSmallImageId(counterLocalService.increment());
1942 }
1943
1944 article.setSmallImageURL(smallImageURL);
1945
1946 journalArticlePersistence.update(article, false);
1947
1948 updateUrlTitles(groupId, articleId, article.getUrlTitle());
1949
1950
1952 ExpandoBridge expandoBridge = article.getExpandoBridge();
1953
1954 expandoBridge.setAttributes(serviceContext);
1955
1956
1958 saveImages(
1959 smallImage, article.getSmallImageId(), smallFile, smallBytes);
1960
1961
1963 String[] tagsCategories = serviceContext.getTagsCategories();
1964 String[] tagsEntries = serviceContext.getTagsEntries();
1965
1966 updateTagsAsset(userId, article, tagsCategories, tagsEntries);
1967
1968
1970 PortletPreferences preferences =
1971 ServiceContextUtil.getPortletPreferences(serviceContext);
1972
1973 if (incrementVersion) {
1974 try {
1975 sendEmail(article, articleURL, preferences, "requested");
1976 }
1977 catch (IOException ioe) {
1978 throw new SystemException(ioe);
1979 }
1980 }
1981
1982
1984 reIndex(article);
1985
1986 return article;
1987 }
1988
1989 public JournalArticle updateContent(
1990 long groupId, String articleId, double version, String content)
1991 throws PortalException, SystemException {
1992
1993 JournalArticle article = journalArticlePersistence.findByG_A_V(
1994 groupId, articleId, version);
1995
1996 article.setContent(content);
1997
1998 journalArticlePersistence.update(article, false);
1999
2000 return article;
2001 }
2002
2003 public void updateTagsAsset(
2004 long userId, JournalArticle article, String[] tagsCategories,
2005 String[] tagsEntries)
2006 throws PortalException, SystemException {
2007
2008
2011 Date[] dateInterval = getDateInterval(
2012 article.getGroupId(), article.getArticleId(),
2013 article.getDisplayDate(), article.getExpirationDate());
2014
2015 Date displayDate = dateInterval[0];
2016 Date expirationDate = dateInterval[1];
2017
2018 boolean visible = article.getApproved();
2019
2020 if (!visible &&
2021 (article.getVersion() != JournalArticleImpl.DEFAULT_VERSION)) {
2022
2023 int approvedArticlesCount =
2024 journalArticlePersistence.countByG_A_A(
2025 article.getGroupId(), article.getArticleId(), true);
2026
2027 if (approvedArticlesCount > 0) {
2028 visible = true;
2029 }
2030 }
2031
2032 tagsAssetLocalService.updateAsset(
2033 userId, article.getGroupId(), JournalArticle.class.getName(),
2034 article.getResourcePrimKey(), tagsCategories, tagsEntries,
2035 visible, null, null, displayDate, expirationDate,
2036 ContentTypes.TEXT_HTML, article.getTitle(),
2037 article.getDescription(), null, null, 0, 0, null, false);
2038 }
2039
2040 protected void checkStructure(JournalArticle article)
2041 throws DocumentException, PortalException, SystemException {
2042
2043 JournalStructure structure = journalStructurePersistence.findByG_S(
2044 article.getGroupId(), article.getStructureId());
2045
2046 String content = GetterUtil.getString(article.getContent());
2047
2048 Document contentDoc = SAXReaderUtil.read(content);
2049 Document xsdDoc = SAXReaderUtil.read(structure.getXsd());
2050
2051 try {
2052 checkStructure(contentDoc, xsdDoc.getRootElement());
2053 }
2054 catch (StructureXsdException sxsde) {
2055 long groupId = article.getGroupId();
2056 String articleId = article.getArticleId();
2057 double version = article.getVersion();
2058
2059 if (_log.isWarnEnabled()) {
2060 _log.warn(
2061 "Article {groupId=" + groupId + ", articleId=" +
2062 articleId + ", version=" + version +
2063 "} has content that does not match its " +
2064 "structure: " + sxsde.getMessage());
2065 }
2066 }
2067 }
2068
2069 protected void checkStructure(Document contentDoc, Element root)
2070 throws PortalException {
2071
2072 for (Element el : root.elements()) {
2073 checkStructureField(el, contentDoc);
2074
2075 checkStructure(contentDoc, el);
2076 }
2077 }
2078
2079 protected void checkStructureField(Element el, Document contentDoc)
2080 throws PortalException {
2081
2082 StringBuilder elPath = new StringBuilder();
2083
2084 elPath.append(el.attributeValue("name"));
2085
2086 Element elParent = el.getParent();
2087
2088 for (;;) {
2089 if ((elParent == null) ||
2090 (elParent.getName().equals("root"))) {
2091
2092 break;
2093 }
2094
2095 elPath.insert(
2096 0, elParent.attributeValue("name") + StringPool.COMMA);
2097
2098 elParent = elParent.getParent();
2099 }
2100
2101 String[] elPathNames = StringUtil.split(elPath.toString());
2102
2103 Element contentEl = contentDoc.getRootElement();
2104
2105 for (int i = 0; i < elPathNames.length; i++) {
2106 boolean foundEl = false;
2107
2108 for (Element tempEl : contentEl.elements()) {
2109 if (elPathNames[i].equals(
2110 tempEl.attributeValue("name", StringPool.BLANK))) {
2111
2112 contentEl = tempEl;
2113 foundEl = true;
2114
2115 break;
2116 }
2117 }
2118
2119 if (!foundEl) {
2120 String elType = contentEl.attributeValue(
2121 "type", StringPool.BLANK);
2122
2123 if (!elType.equals("list") && !elType.equals("multi-list")) {
2124 throw new StructureXsdException(elPath.toString());
2125 }
2126
2127 break;
2128 }
2129 }
2130 }
2131
2132 protected void copyArticleImages(
2133 JournalArticle oldArticle, JournalArticle newArticle)
2134 throws Exception {
2135
2136 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
2137
2138 XPath xpathSelector = SAXReaderUtil.createXPath(
2139 "//dynamic-element[@type='image']");
2140
2141 List<Node> imageNodes = xpathSelector.selectNodes(contentDoc);
2142
2143 for (Node imageNode : imageNodes) {
2144 Element imageEl = (Element)imageNode;
2145
2146 String instanceId = imageEl.attributeValue("instance-id");
2147 String name = imageEl.attributeValue("name");
2148
2149 List<Element> dynamicContentEls = imageEl.elements(
2150 "dynamic-content");
2151
2152 for (Element dynamicContentEl : dynamicContentEls) {
2153 long imageId = GetterUtil.getLong(
2154 dynamicContentEl.attributeValue("id"));
2155 String languageId = dynamicContentEl.attributeValue(
2156 "language-id");
2157
2158 Image oldImage = null;
2159
2160 try {
2161 oldImage = imageLocalService.getImage(imageId);
2162 }
2163 catch (NoSuchImageException nsie) {
2164 continue;
2165 }
2166
2167 imageId = journalArticleImageLocalService.getArticleImageId(
2168 newArticle.getGroupId(), newArticle.getArticleId(),
2169 newArticle.getVersion(), instanceId, name, languageId);
2170
2171 imageLocalService.updateImage(imageId, oldImage.getTextObj());
2172
2173 String elContent =
2174 "/image/journal/article?img_id=" + imageId + "&t=" +
2175 ImageServletTokenUtil.getToken(imageId);
2176
2177 dynamicContentEl.setText(elContent);
2178 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
2179 }
2180 }
2181
2182 newArticle.setContent(contentDoc.formattedString());
2183 }
2184
2185 protected String format(
2186 long groupId, String articleId, double version,
2187 boolean incrementVersion, String content, String structureId,
2188 Map<String, byte[]> images)
2189 throws PortalException, SystemException {
2190
2191 if (Validator.isNotNull(structureId)) {
2192 Document doc = null;
2193
2194 try {
2195 doc = SAXReaderUtil.read(content);
2196
2197 Element root = doc.getRootElement();
2198
2199 format(
2200 groupId, articleId, version, incrementVersion, root,
2201 images);
2202
2203 content = JournalUtil.formatXML(doc);
2204 }
2205 catch (DocumentException de) {
2206 _log.error(de);
2207 }
2208 catch (IOException ioe) {
2209 _log.error(ioe);
2210 }
2211 }
2212
2213 content = HtmlUtil.replaceMsWordCharacters(content);
2214
2215 return content;
2216 }
2217
2218 protected void format(
2219 long groupId, String articleId, double version,
2220 boolean incrementVersion, Element root, Map<String, byte[]> images)
2221 throws PortalException, SystemException {
2222
2223 for (Element el : root.elements()) {
2224 String elInstanceId = el.attributeValue(
2225 "instance-id", StringPool.BLANK);
2226 String elName = el.attributeValue("name", StringPool.BLANK);
2227 String elType = el.attributeValue("type", StringPool.BLANK);
2228
2229 if (elType.equals("image")) {
2230 formatImage(
2231 groupId, articleId, version, incrementVersion, el,
2232 elInstanceId, elName, images);
2233 }
2234
2254
2255 format(groupId, articleId, version, incrementVersion, el, images);
2256 }
2257 }
2258
2259 protected void formatImage(
2260 long groupId, String articleId, double version,
2261 boolean incrementVersion, Element el, String elInstanceId,
2262 String elName, Map<String, byte[]> images)
2263 throws PortalException, SystemException {
2264
2265 List<Element> imageContents = el.elements("dynamic-content");
2266
2267 for (Element dynamicContent : imageContents) {
2268 String elLanguage = dynamicContent.attributeValue(
2269 "language-id", StringPool.BLANK);
2270
2271 if (!elLanguage.equals(StringPool.BLANK)) {
2272 elLanguage = "_" + elLanguage;
2273 }
2274
2275 long imageId =
2276 journalArticleImageLocalService.getArticleImageId(
2277 groupId, articleId, version, elInstanceId, elName,
2278 elLanguage);
2279
2280 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
2281
2282 long oldImageId = 0;
2283
2284 if ((oldVersion >= 1) && incrementVersion) {
2285 oldImageId =
2286 journalArticleImageLocalService.getArticleImageId(
2287 groupId, articleId, oldVersion, elInstanceId, elName,
2288 elLanguage);
2289 }
2290
2291 String elContent =
2292 "/image/journal/article?img_id=" + imageId + "&t=" +
2293 ImageServletTokenUtil.getToken(imageId);
2294
2295 if (dynamicContent.getText().equals("delete")) {
2296 dynamicContent.setText(StringPool.BLANK);
2297
2298 imageLocalService.deleteImage(imageId);
2299
2300 String defaultElLanguage = "";
2301
2302 if (!Validator.isNotNull(elLanguage)) {
2303 defaultElLanguage =
2304 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2305 }
2306
2307 long defaultImageId =
2308 journalArticleImageLocalService.getArticleImageId(
2309 groupId, articleId, version, elInstanceId, elName,
2310 defaultElLanguage);
2311
2312 imageLocalService.deleteImage(defaultImageId);
2313
2314 continue;
2315 }
2316
2317 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
2318
2319 if (bytes != null && (bytes.length > 0)) {
2320 dynamicContent.setText(elContent);
2321 dynamicContent.addAttribute("id", String.valueOf(imageId));
2322
2323 imageLocalService.updateImage(imageId, bytes);
2324
2325 continue;
2326 }
2327
2328 if ((version > JournalArticleImpl.DEFAULT_VERSION) &&
2329 (incrementVersion)) {
2330
2331 Image oldImage = null;
2332
2333 if (oldImageId > 0) {
2334 oldImage = imageLocalService.getImage(oldImageId);
2335 }
2336
2337 if (oldImage != null) {
2338 dynamicContent.setText(elContent);
2339 dynamicContent.addAttribute("id", String.valueOf(imageId));
2340
2341 bytes = oldImage.getTextObj();
2342
2343 imageLocalService.updateImage(imageId, bytes);
2344 }
2345
2346 continue;
2347 }
2348
2349 Image image = imageLocalService.getImage(imageId);
2350
2351 if (image != null) {
2352 dynamicContent.setText(elContent);
2353 dynamicContent.addAttribute("id", String.valueOf(imageId));
2354
2355 continue;
2356 }
2357
2358 long contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2359 dynamicContent.getText(), "img_id"));
2360
2361 if (contentImageId <= 0) {
2362 contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2363 dynamicContent.getText(), "img_id", false));
2364 }
2365
2366 if (contentImageId > 0) {
2367 image = imageLocalService.getImage(contentImageId);
2368
2369 if (image != null) {
2370 dynamicContent.addAttribute(
2371 "id", String.valueOf(contentImageId));
2372
2373 continue;
2374 }
2375 }
2376
2377 String defaultElLanguage = "";
2378
2379 if (!Validator.isNotNull(elLanguage)) {
2380 defaultElLanguage =
2381 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2382 }
2383
2384 long defaultImageId =
2385 journalArticleImageLocalService.getArticleImageId(
2386 groupId, articleId, version, elInstanceId, elName,
2387 defaultElLanguage);
2388
2389 Image defaultImage = imageLocalService.getImage(defaultImageId);
2390
2391 if (defaultImage != null) {
2392 dynamicContent.setText(elContent);
2393 dynamicContent.addAttribute(
2394 "id", String.valueOf(defaultImageId));
2395
2396 bytes = defaultImage.getTextObj();
2397
2398 imageLocalService.updateImage(defaultImageId, bytes);
2399
2400 continue;
2401 }
2402
2403 dynamicContent.setText(StringPool.BLANK);
2404 }
2405 }
2406
2407 protected Date[] getDateInterval(
2408 long groupId, String articleId, Date earliestDisplayDate,
2409 Date latestExpirationDate)
2410 throws SystemException {
2411
2412 Date[] dateInterval = new Date[2];
2413
2414 List<JournalArticle> articles = journalArticlePersistence.findByG_A_A(
2415 groupId, articleId, true);
2416
2417 boolean expiringArticle = true;
2418
2419 if (latestExpirationDate == null) {
2420 expiringArticle = false;
2421 }
2422
2423 for (JournalArticle article : articles) {
2424 if ((earliestDisplayDate == null) ||
2425 ((article.getDisplayDate() != null) &&
2426 earliestDisplayDate.after(article.getDisplayDate()))) {
2427
2428 earliestDisplayDate = article.getDisplayDate();
2429 }
2430
2431 if (expiringArticle &&
2432 ((latestExpirationDate == null) ||
2433 ((article.getExpirationDate() != null) &&
2434 latestExpirationDate.before(article.getExpirationDate())))) {
2435
2436 latestExpirationDate = article.getExpirationDate();
2437 }
2438
2439 if (expiringArticle && (article.getExpirationDate() == null)) {
2440 latestExpirationDate = null;
2441 expiringArticle = false;
2442 }
2443 }
2444
2445 dateInterval[0] = earliestDisplayDate;
2446 dateInterval[1] = latestExpirationDate;
2447
2448 return dateInterval;
2449 }
2450
2451 protected String[] getTagsCategories(JournalArticle article)
2452 throws SystemException {
2453
2454 List<TagsEntry> tagsEntries = tagsEntryLocalService.getEntries(
2455 JournalArticle.class.getName(), article.getPrimaryKey(), false);
2456
2457 return StringUtil.split(ListUtil.toString(tagsEntries, "name"));
2458 }
2459
2460 protected String[] getTagsEntries(JournalArticle article)
2461 throws SystemException {
2462
2463 List<TagsEntry> tagsEntries = tagsEntryLocalService.getEntries(
2464 JournalArticle.class.getName(), article.getPrimaryKey(), true);
2465
2466 return StringUtil.split(ListUtil.toString(tagsEntries, "name"));
2467 }
2468
2469 protected String getUniqueUrlTitle(
2470 long id, long groupId, String articleId, String title)
2471 throws PortalException, SystemException {
2472
2473 String urlTitle = getUrlTitle(id, title);
2474
2475 String newUrlTitle = urlTitle;
2476
2477 for (int i = 1;; i++) {
2478 JournalArticle article = null;
2479
2480 try {
2481 article = getArticleByUrlTitle(groupId, newUrlTitle);
2482 }
2483 catch (NoSuchArticleException nsae) {
2484 }
2485
2486 if ((article == null) || article.getArticleId().equals(articleId)) {
2487 break;
2488 }
2489 else {
2490 newUrlTitle = urlTitle + StringPool.DASH + i;
2491 }
2492 }
2493
2494 return newUrlTitle;
2495 }
2496
2497 protected String getUrlTitle(long id, String title) {
2498 title = title.trim().toLowerCase();
2499
2500 if (Validator.isNull(title) || Validator.isNumber(title) ||
2501 title.equals("rss")) {
2502
2503 return String.valueOf(id);
2504 }
2505 else {
2506 return FriendlyURLNormalizer.normalize(
2507 title, _URL_TITLE_REPLACE_CHARS);
2508 }
2509 }
2510
2511 protected void reIndexArticles(long companyId) throws SystemException {
2512 int count = journalArticlePersistence.countByCompanyId(companyId);
2513
2514 int pages = count / Indexer.DEFAULT_INTERVAL;
2515
2516 for (int i = 0; i <= pages; i++) {
2517 int start = (i * Indexer.DEFAULT_INTERVAL);
2518 int end = start + Indexer.DEFAULT_INTERVAL;
2519
2520 reIndexArticles(companyId, start, end);
2521 }
2522 }
2523
2524 protected void reIndexArticles(long companyId, int start, int end)
2525 throws SystemException {
2526
2527 List<JournalArticle> articles =
2528 journalArticlePersistence.findByCompanyId(companyId, start, end);
2529
2530 for (JournalArticle article : articles) {
2531 reIndex(article);
2532 }
2533 }
2534
2535 protected void saveImages(
2536 boolean smallImage, long smallImageId, File smallFile,
2537 byte[] smallBytes)
2538 throws PortalException, SystemException {
2539
2540 if (smallImage) {
2541 if ((smallFile != null) && (smallBytes != null)) {
2542 imageLocalService.updateImage(smallImageId, smallBytes);
2543 }
2544 }
2545 else {
2546 imageLocalService.deleteImage(smallImageId);
2547 }
2548 }
2549
2550 protected void sendEmail(
2551 JournalArticle article, String articleURL,
2552 PortletPreferences preferences, String emailType)
2553 throws IOException, PortalException, SystemException {
2554
2555 if (preferences == null) {
2556 return;
2557 }
2558 else if (emailType.equals("denied") &&
2559 JournalUtil.getEmailArticleApprovalDeniedEnabled(preferences)) {
2560 }
2561 else if (emailType.equals("granted") &&
2562 JournalUtil.getEmailArticleApprovalGrantedEnabled(
2563 preferences)) {
2564 }
2565 else if (emailType.equals("requested") &&
2566 JournalUtil.getEmailArticleApprovalRequestedEnabled(
2567 preferences)) {
2568 }
2569 else if (emailType.equals("review") &&
2570 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
2571 }
2572 else {
2573 return;
2574 }
2575
2576 Company company = companyPersistence.findByPrimaryKey(
2577 article.getCompanyId());
2578
2579 User user = userPersistence.findByPrimaryKey(article.getUserId());
2580
2581 articleURL +=
2582 "&groupId=" + article.getGroupId() + "&articleId=" +
2583 article.getArticleId() + "&version=" + article.getVersion();
2584
2585 String portletName = PortalUtil.getPortletTitle(
2586 PortletKeys.JOURNAL, user);
2587
2588 String fromName = JournalUtil.getEmailFromName(preferences);
2589 String fromAddress = JournalUtil.getEmailFromAddress(preferences);
2590
2591 String toName = user.getFullName();
2592 String toAddress = user.getEmailAddress();
2593
2594 if (emailType.equals("requested") ||
2595 emailType.equals("review")) {
2596
2597 String tempToName = fromName;
2598 String tempToAddress = fromAddress;
2599
2600 fromName = toName;
2601 fromAddress = toAddress;
2602
2603 toName = tempToName;
2604 toAddress = tempToAddress;
2605 }
2606
2607 String subject = null;
2608 String body = null;
2609
2610 if (emailType.equals("denied")) {
2611 subject =
2612 JournalUtil.getEmailArticleApprovalDeniedSubject(preferences);
2613 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
2614 }
2615 else if (emailType.equals("granted")) {
2616 subject =
2617 JournalUtil.getEmailArticleApprovalGrantedSubject(preferences);
2618 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
2619 }
2620 else if (emailType.equals("requested")) {
2621 subject =
2622 JournalUtil.getEmailArticleApprovalRequestedSubject(
2623 preferences);
2624 body = JournalUtil.getEmailArticleApprovalRequestedBody(
2625 preferences);
2626 }
2627 else if (emailType.equals("review")) {
2628 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
2629 body = JournalUtil.getEmailArticleReviewBody(preferences);
2630 }
2631
2632 subject = StringUtil.replace(
2633 subject,
2634 new String[] {
2635 "[$ARTICLE_ID$]",
2636 "[$ARTICLE_TITLE$]",
2637 "[$ARTICLE_URL$]",
2638 "[$ARTICLE_VERSION$]",
2639 "[$FROM_ADDRESS$]",
2640 "[$FROM_NAME$]",
2641 "[$PORTAL_URL$]",
2642 "[$PORTLET_NAME$]",
2643 "[$TO_ADDRESS$]",
2644 "[$TO_NAME$]"
2645 },
2646 new String[] {
2647 article.getArticleId(),
2648 article.getTitle(),
2649 articleURL,
2650 String.valueOf(article.getVersion()),
2651 fromAddress,
2652 fromName,
2653 company.getVirtualHost(),
2654 portletName,
2655 toAddress,
2656 toName,
2657 });
2658
2659 body = StringUtil.replace(
2660 body,
2661 new String[] {
2662 "[$ARTICLE_ID$]",
2663 "[$ARTICLE_TITLE$]",
2664 "[$ARTICLE_URL$]",
2665 "[$ARTICLE_VERSION$]",
2666 "[$FROM_ADDRESS$]",
2667 "[$FROM_NAME$]",
2668 "[$PORTAL_URL$]",
2669 "[$PORTLET_NAME$]",
2670 "[$TO_ADDRESS$]",
2671 "[$TO_NAME$]"
2672 },
2673 new String[] {
2674 article.getArticleId(),
2675 article.getTitle(),
2676 articleURL,
2677 String.valueOf(article.getVersion()),
2678 fromAddress,
2679 fromName,
2680 company.getVirtualHost(),
2681 portletName,
2682 toAddress,
2683 toName,
2684 });
2685
2686 InternetAddress from = new InternetAddress(fromAddress, fromName);
2687
2688 InternetAddress to = new InternetAddress(toAddress, toName);
2689
2690 MailMessage message = new MailMessage(from, to, subject, body, true);
2691
2692 mailService.sendEmail(message);
2693 }
2694
2695 protected void updateUrlTitles(
2696 long groupId, String articleId, String urlTitle)
2697 throws SystemException {
2698
2699 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
2700 groupId, articleId);
2701
2702 for (JournalArticle article : articles) {
2703 if (!article.getUrlTitle().equals(urlTitle)) {
2704 article.setUrlTitle(urlTitle);
2705
2706 journalArticlePersistence.update(article, false);
2707 }
2708 }
2709 }
2710
2711 protected void validate(String articleId) throws PortalException {
2712 if ((Validator.isNull(articleId)) ||
2713 (articleId.indexOf(StringPool.SPACE) != -1)) {
2714
2715 throw new ArticleIdException();
2716 }
2717 }
2718
2719 protected void validate(
2720 long groupId, String articleId, boolean autoArticleId,
2721 double version, String title, String content, String type,
2722 String structureId, String templateId, boolean smallImage,
2723 String smallImageURL, File smallFile, byte[] smallBytes)
2724 throws PortalException, SystemException {
2725
2726 if (!autoArticleId) {
2727 validate(articleId);
2728
2729 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
2730 groupId, articleId, version);
2731
2732 if (article != null) {
2733 throw new DuplicateArticleIdException();
2734 }
2735 }
2736
2737 validate(
2738 groupId, title, content, type, structureId, templateId,
2739 smallImage, smallImageURL, smallFile, smallBytes);
2740 }
2741
2742 protected void validate(
2743 long groupId, String title, String content, String type,
2744 String structureId, String templateId, boolean smallImage,
2745 String smallImageURL, File smallFile, byte[] smallBytes)
2746 throws PortalException, SystemException {
2747
2748 if (Validator.isNull(title)) {
2749 throw new ArticleTitleException();
2750 }
2751 else if (Validator.isNull(content)) {
2752 throw new ArticleContentException();
2753 }
2754 else if (Validator.isNull(type)) {
2755 throw new ArticleTypeException();
2756 }
2757
2758 if (Validator.isNotNull(structureId)) {
2759 journalStructurePersistence.findByG_S(groupId, structureId);
2760
2761 JournalTemplate template = journalTemplatePersistence.findByG_T(
2762 groupId, templateId);
2763
2764 if (!template.getStructureId().equals(structureId)) {
2765 throw new NoSuchTemplateException();
2766 }
2767 }
2768
2769 String[] imageExtensions = PrefsPropsUtil.getStringArray(
2770 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
2771
2772 if (smallImage && Validator.isNull(smallImageURL) &&
2773 smallFile != null && smallBytes != null) {
2774
2775 String smallImageName = smallFile.getName();
2776
2777 if (smallImageName != null) {
2778 boolean validSmallImageExtension = false;
2779
2780 for (int i = 0; i < imageExtensions.length; i++) {
2781 if (StringPool.STAR.equals(imageExtensions[i]) ||
2782 StringUtil.endsWith(
2783 smallImageName, imageExtensions[i])) {
2784
2785 validSmallImageExtension = true;
2786
2787 break;
2788 }
2789 }
2790
2791 if (!validSmallImageExtension) {
2792 throw new ArticleSmallImageNameException(smallImageName);
2793 }
2794 }
2795
2796 long smallImageMaxSize = PrefsPropsUtil.getLong(
2797 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
2798
2799 if ((smallImageMaxSize > 0) &&
2800 ((smallBytes == null) ||
2801 (smallBytes.length > smallImageMaxSize))) {
2802
2803 throw new ArticleSmallImageSizeException();
2804 }
2805 }
2806 }
2807
2808 private static final String _TOKEN_PAGE_BREAK = PropsUtil.get(
2809 PropsKeys.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
2810
2811 private static final char[] _URL_TITLE_REPLACE_CHARS = new char[] {
2812 '.', '/'
2813 };
2814
2815 private static Log _log =
2816 LogFactoryUtil.getLog(JournalArticleLocalServiceImpl.class);
2817
2818}