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