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