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