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