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