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