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