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