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