001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.NoSuchImageException;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
024 import com.liferay.portal.kernel.search.Field;
025 import com.liferay.portal.kernel.search.Hits;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.search.QueryConfig;
029 import com.liferay.portal.kernel.search.SearchContext;
030 import com.liferay.portal.kernel.search.Sort;
031 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
032 import com.liferay.portal.kernel.util.CharPool;
033 import com.liferay.portal.kernel.util.ContentTypes;
034 import com.liferay.portal.kernel.util.FileUtil;
035 import com.liferay.portal.kernel.util.GetterUtil;
036 import com.liferay.portal.kernel.util.HtmlUtil;
037 import com.liferay.portal.kernel.util.HttpUtil;
038 import com.liferay.portal.kernel.util.ListUtil;
039 import com.liferay.portal.kernel.util.LocaleUtil;
040 import com.liferay.portal.kernel.util.LocalizationUtil;
041 import com.liferay.portal.kernel.util.MathUtil;
042 import com.liferay.portal.kernel.util.OrderByComparator;
043 import com.liferay.portal.kernel.util.PropsKeys;
044 import com.liferay.portal.kernel.util.StringPool;
045 import com.liferay.portal.kernel.util.StringUtil;
046 import com.liferay.portal.kernel.util.Time;
047 import com.liferay.portal.kernel.util.Validator;
048 import com.liferay.portal.kernel.workflow.WorkflowConstants;
049 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
050 import com.liferay.portal.kernel.xml.Document;
051 import com.liferay.portal.kernel.xml.DocumentException;
052 import com.liferay.portal.kernel.xml.Element;
053 import com.liferay.portal.kernel.xml.Node;
054 import com.liferay.portal.kernel.xml.SAXReaderUtil;
055 import com.liferay.portal.kernel.xml.XPath;
056 import com.liferay.portal.model.Company;
057 import com.liferay.portal.model.Group;
058 import com.liferay.portal.model.Image;
059 import com.liferay.portal.model.ModelHintsUtil;
060 import com.liferay.portal.model.ResourceConstants;
061 import com.liferay.portal.model.User;
062 import com.liferay.portal.service.ServiceContext;
063 import com.liferay.portal.service.ServiceContextUtil;
064 import com.liferay.portal.servlet.filters.cache.CacheUtil;
065 import com.liferay.portal.theme.ThemeDisplay;
066 import com.liferay.portal.util.PortalUtil;
067 import com.liferay.portal.util.PortletKeys;
068 import com.liferay.portal.util.PrefsPropsUtil;
069 import com.liferay.portal.util.PropsValues;
070 import com.liferay.portal.util.SubscriptionSender;
071 import com.liferay.portal.webserver.WebServerServletTokenUtil;
072 import com.liferay.portlet.asset.NoSuchEntryException;
073 import com.liferay.portlet.asset.model.AssetEntry;
074 import com.liferay.portlet.asset.model.AssetLink;
075 import com.liferay.portlet.asset.model.AssetLinkConstants;
076 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
077 import com.liferay.portlet.expando.model.ExpandoBridge;
078 import com.liferay.portlet.journal.ArticleContentException;
079 import com.liferay.portlet.journal.ArticleDisplayDateException;
080 import com.liferay.portlet.journal.ArticleExpirationDateException;
081 import com.liferay.portlet.journal.ArticleIdException;
082 import com.liferay.portlet.journal.ArticleReviewDateException;
083 import com.liferay.portlet.journal.ArticleSmallImageNameException;
084 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
085 import com.liferay.portlet.journal.ArticleTitleException;
086 import com.liferay.portlet.journal.ArticleTypeException;
087 import com.liferay.portlet.journal.ArticleVersionException;
088 import com.liferay.portlet.journal.DuplicateArticleIdException;
089 import com.liferay.portlet.journal.NoSuchArticleException;
090 import com.liferay.portlet.journal.NoSuchArticleResourceException;
091 import com.liferay.portlet.journal.NoSuchStructureException;
092 import com.liferay.portlet.journal.NoSuchTemplateException;
093 import com.liferay.portlet.journal.StructureXsdException;
094 import com.liferay.portlet.journal.model.JournalArticle;
095 import com.liferay.portlet.journal.model.JournalArticleConstants;
096 import com.liferay.portlet.journal.model.JournalArticleDisplay;
097 import com.liferay.portlet.journal.model.JournalArticleResource;
098 import com.liferay.portlet.journal.model.JournalStructure;
099 import com.liferay.portlet.journal.model.JournalTemplate;
100 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
101 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
102 import com.liferay.portlet.journal.util.JournalUtil;
103 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
104 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
105 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
106
107 import java.io.File;
108 import java.io.IOException;
109 import java.io.Serializable;
110
111 import java.util.Calendar;
112 import java.util.Date;
113 import java.util.HashMap;
114 import java.util.HashSet;
115 import java.util.LinkedHashMap;
116 import java.util.List;
117 import java.util.Locale;
118 import java.util.Map;
119 import java.util.Set;
120
121 import javax.portlet.PortletPreferences;
122
123
129 public class JournalArticleLocalServiceImpl
130 extends JournalArticleLocalServiceBaseImpl {
131
132 public JournalArticle addArticle(
133 long userId, long groupId, long classNameId, long classPK,
134 String articleId, boolean autoArticleId, double version,
135 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
136 String content, String type, String structureId, String templateId,
137 String layoutUuid, int displayDateMonth, int displayDateDay,
138 int displayDateYear, int displayDateHour, int displayDateMinute,
139 int expirationDateMonth, int expirationDateDay,
140 int expirationDateYear, int expirationDateHour,
141 int expirationDateMinute, boolean neverExpire, int reviewDateMonth,
142 int reviewDateDay, int reviewDateYear, int reviewDateHour,
143 int reviewDateMinute, boolean neverReview, boolean indexable,
144 boolean smallImage, String smallImageURL, File smallImageFile,
145 Map<String, byte[]> images, String articleURL,
146 ServiceContext serviceContext)
147 throws PortalException, SystemException {
148
149
150
151 User user = userPersistence.findByPrimaryKey(userId);
152 articleId = articleId.trim().toUpperCase();
153
154 Date displayDate = PortalUtil.getDate(
155 displayDateMonth, displayDateDay, displayDateYear,
156 displayDateHour, displayDateMinute, user.getTimeZone(),
157 new ArticleDisplayDateException());
158
159 Date expirationDate = null;
160
161 if (!neverExpire) {
162 expirationDate = PortalUtil.getDate(
163 expirationDateMonth, expirationDateDay, expirationDateYear,
164 expirationDateHour, expirationDateMinute, user.getTimeZone(),
165 new ArticleExpirationDateException());
166 }
167
168 Date reviewDate = null;
169
170 if (!neverReview) {
171 reviewDate = PortalUtil.getDate(
172 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
173 reviewDateMinute, user.getTimeZone(),
174 new ArticleReviewDateException());
175 }
176
177 byte[] smallImageBytes = null;
178
179 try {
180 smallImageBytes = FileUtil.getBytes(smallImageFile);
181 }
182 catch (IOException ioe) {
183 }
184
185 Date now = new Date();
186
187 validate(
188 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
189 version, titleMap, content, type, structureId, templateId,
190 smallImage, smallImageURL, smallImageFile, smallImageBytes);
191
192 if (autoArticleId) {
193 articleId = String.valueOf(counterLocalService.increment());
194 }
195
196 long id = counterLocalService.increment();
197
198 long resourcePrimKey =
199 journalArticleResourceLocalService.getArticleResourcePrimKey(
200 serviceContext.getUuid(), groupId, articleId);
201
202 JournalArticle article = journalArticlePersistence.create(id);
203
204 Locale locale = LocaleUtil.getDefault();
205
206 String defaultLanguageId = GetterUtil.getString(
207 serviceContext.getAttribute("defaultLanguageId"));
208
209 if (Validator.isNotNull(defaultLanguageId)) {
210 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
211 }
212
213 String title = titleMap.get(locale);
214
215 content = format(
216 user, groupId, articleId, version, false, content, structureId,
217 images);
218
219 article.setResourcePrimKey(resourcePrimKey);
220 article.setGroupId(groupId);
221 article.setCompanyId(user.getCompanyId());
222 article.setUserId(user.getUserId());
223 article.setUserName(user.getFullName());
224 article.setCreateDate(serviceContext.getCreateDate(now));
225 article.setModifiedDate(serviceContext.getModifiedDate(now));
226 article.setClassNameId(classNameId);
227 article.setClassPK(classPK);
228 article.setArticleId(articleId);
229 article.setVersion(version);
230 article.setTitleMap(titleMap, locale);
231 article.setUrlTitle(getUniqueUrlTitle(id, groupId, articleId, title));
232 article.setDescriptionMap(descriptionMap, locale);
233 article.setContent(content);
234 article.setType(type);
235 article.setStructureId(structureId);
236 article.setTemplateId(templateId);
237 article.setLayoutUuid(layoutUuid);
238 article.setDisplayDate(displayDate);
239 article.setExpirationDate(expirationDate);
240 article.setReviewDate(reviewDate);
241 article.setIndexable(indexable);
242 article.setSmallImage(smallImage);
243 article.setSmallImageId(counterLocalService.increment());
244 article.setSmallImageURL(smallImageURL);
245
246 if ((expirationDate == null) || expirationDate.after(now)) {
247 article.setStatus(WorkflowConstants.STATUS_DRAFT);
248 }
249 else {
250 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
251 }
252
253 journalArticlePersistence.update(article, false);
254
255
256
257 if (serviceContext.getAddGroupPermissions() ||
258 serviceContext.getAddGuestPermissions()) {
259
260 addArticleResources(
261 article, serviceContext.getAddGroupPermissions(),
262 serviceContext.getAddGuestPermissions());
263 }
264 else {
265 addArticleResources(
266 article, serviceContext.getGroupPermissions(),
267 serviceContext.getGuestPermissions());
268 }
269
270
271
272 ExpandoBridge expandoBridge = article.getExpandoBridge();
273
274 expandoBridge.setAttributes(serviceContext);
275
276
277
278 saveImages(
279 smallImage, article.getSmallImageId(), smallImageFile,
280 smallImageBytes);
281
282
283
284 updateAsset(
285 userId, article, serviceContext.getAssetCategoryIds(),
286 serviceContext.getAssetTagNames(),
287 serviceContext.getAssetLinkEntryIds());
288
289
290
291 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
292 mbMessageLocalService.addDiscussionMessage(
293 userId, article.getUserName(), groupId,
294 JournalArticle.class.getName(), resourcePrimKey,
295 WorkflowConstants.ACTION_PUBLISH);
296 }
297
298
299
300 PortletPreferences preferences =
301 ServiceContextUtil.getPortletPreferences(serviceContext);
302
303 sendEmail(article, articleURL, preferences, "requested");
304
305
306
307 if (classNameId == 0) {
308 WorkflowHandlerRegistryUtil.startWorkflowInstance(
309 user.getCompanyId(), groupId, userId,
310 JournalArticle.class.getName(), article.getId(), article,
311 serviceContext);
312
313 if (serviceContext.getWorkflowAction() !=
314 WorkflowConstants.ACTION_PUBLISH) {
315
316
317
318 Indexer indexer = IndexerRegistryUtil.getIndexer(
319 JournalArticle.class);
320
321 indexer.reindex(article);
322 }
323 }
324 else {
325 updateStatus(
326 userId, article, WorkflowConstants.STATUS_APPROVED, null,
327 serviceContext);
328 }
329
330 return article;
331 }
332
333 public void addArticleResources(
334 JournalArticle article, boolean addGroupPermissions,
335 boolean addGuestPermissions)
336 throws PortalException, SystemException {
337
338 resourceLocalService.addResources(
339 article.getCompanyId(), article.getGroupId(),
340 article.getUserId(), JournalArticle.class.getName(),
341 article.getResourcePrimKey(), false, addGroupPermissions,
342 addGuestPermissions);
343 }
344
345 public void addArticleResources(
346 JournalArticle article, String[] groupPermissions,
347 String[] guestPermissions)
348 throws PortalException, SystemException {
349
350 resourceLocalService.addModelResources(
351 article.getCompanyId(), article.getGroupId(),
352 article.getUserId(), JournalArticle.class.getName(),
353 article.getResourcePrimKey(), groupPermissions, guestPermissions);
354 }
355
356 public void addArticleResources(
357 long groupId, String articleId, boolean addGroupPermissions,
358 boolean addGuestPermissions)
359 throws PortalException, SystemException {
360
361 JournalArticle article = getLatestArticle(groupId, articleId);
362
363 addArticleResources(
364 article, addGroupPermissions, addGuestPermissions);
365 }
366
367 public void addArticleResources(
368 long groupId, String articleId, String[] groupPermissions,
369 String[] guestPermissions)
370 throws PortalException, SystemException {
371
372 JournalArticle article = getLatestArticle(groupId, articleId);
373
374 addArticleResources(article, groupPermissions, guestPermissions);
375 }
376
377 public JournalArticle checkArticleResourcePrimKey(
378 long groupId, String articleId, double version)
379 throws PortalException, SystemException {
380
381 JournalArticle article = journalArticlePersistence.findByG_A_V(
382 groupId, articleId, version);
383
384 if (article.getResourcePrimKey() > 0) {
385 return article;
386 }
387
388 long resourcePrimKey =
389 journalArticleResourceLocalService.getArticleResourcePrimKey(
390 groupId, articleId);
391
392 article.setResourcePrimKey(resourcePrimKey);
393
394 journalArticlePersistence.update(article, false);
395
396 return article;
397 }
398
399 public void checkArticles() throws PortalException, SystemException {
400 Date now = new Date();
401
402 List<JournalArticle> articles =
403 journalArticleFinder.findByExpirationDate(
404 0, WorkflowConstants.STATUS_APPROVED, now);
405
406 if (_log.isDebugEnabled()) {
407 _log.debug("Expiring " + articles.size() + " articles");
408 }
409
410 Set<Long> companyIds = new HashSet<Long>();
411
412 for (JournalArticle article : articles) {
413 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
414
415 journalArticlePersistence.update(article, false);
416
417 if (article.isIndexable()) {
418 Indexer indexer = IndexerRegistryUtil.getIndexer(
419 JournalArticle.class);
420
421 indexer.delete(article);
422 }
423
424 updatePreviousApprovedArticle(article);
425
426 JournalContentUtil.clearCache(
427 article.getGroupId(), article.getArticleId(),
428 article.getTemplateId());
429
430 companyIds.add(article.getCompanyId());
431 }
432
433 for (long companyId : companyIds) {
434 CacheUtil.clearCache(companyId);
435 }
436
437 articles = journalArticleFinder.findByReviewDate(
438 0, now, new Date(now.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL));
439
440 if (_log.isDebugEnabled()) {
441 _log.debug(
442 "Sending review notifications for " + articles.size() +
443 " articles");
444 }
445
446 for (JournalArticle article : articles) {
447 String articleURL = StringPool.BLANK;
448
449 long ownerId = article.getGroupId();
450 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
451 long plid = PortletKeys.PREFS_PLID_SHARED;
452 String portletId = PortletKeys.JOURNAL;
453
454 PortletPreferences preferences =
455 portletPreferencesLocalService.getPreferences(
456 article.getCompanyId(), ownerId, ownerType, plid,
457 portletId);
458
459 sendEmail(article, articleURL, preferences, "review");
460 }
461 }
462
463 public void checkNewLine(long groupId, String articleId, double version)
464 throws PortalException, SystemException {
465
466 JournalArticle article = journalArticlePersistence.findByG_A_V(
467 groupId, articleId, version);
468
469 String content = GetterUtil.getString(article.getContent());
470
471 if (content.indexOf("\\n") != -1) {
472 content = StringUtil.replace(
473 content,
474 new String[] {"\\n", "\\r"},
475 new String[] {"\n", "\r"});
476
477 article.setContent(content);
478
479 journalArticlePersistence.update(article, false);
480 }
481 }
482
483 public void checkStructure(long groupId, String articleId, double version)
484 throws PortalException, SystemException {
485
486 JournalArticle article = journalArticlePersistence.findByG_A_V(
487 groupId, articleId, version);
488
489 if (Validator.isNull(article.getStructureId())) {
490 return;
491 }
492
493 try {
494 checkStructure(article);
495 }
496 catch (DocumentException de) {
497 _log.error(de, de);
498 }
499 }
500
501 public JournalArticle copyArticle(
502 long userId, long groupId, String oldArticleId, String newArticleId,
503 boolean autoArticleId, double version)
504 throws PortalException, SystemException {
505
506
507
508 User user = userPersistence.findByPrimaryKey(userId);
509 oldArticleId = oldArticleId.trim().toUpperCase();
510 newArticleId = newArticleId.trim().toUpperCase();
511 Date now = new Date();
512
513 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
514 groupId, oldArticleId, version);
515
516 if (autoArticleId) {
517 newArticleId = String.valueOf(counterLocalService.increment());
518 }
519 else {
520 validate(groupId, newArticleId);
521 }
522
523 long id = counterLocalService.increment();
524
525 long resourcePrimKey =
526 journalArticleResourceLocalService.getArticleResourcePrimKey(
527 groupId, newArticleId);
528
529 JournalArticle newArticle = journalArticlePersistence.create(id);
530
531 newArticle.setResourcePrimKey(resourcePrimKey);
532 newArticle.setGroupId(groupId);
533 newArticle.setCompanyId(user.getCompanyId());
534 newArticle.setUserId(user.getUserId());
535 newArticle.setUserName(user.getFullName());
536 newArticle.setCreateDate(now);
537 newArticle.setModifiedDate(now);
538 newArticle.setArticleId(newArticleId);
539 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
540 newArticle.setTitle(oldArticle.getTitle());
541 newArticle.setDescription(oldArticle.getDescription());
542
543 try {
544 copyArticleImages(oldArticle, newArticle);
545 }
546 catch (Exception e) {
547 newArticle.setContent(oldArticle.getContent());
548 }
549
550 newArticle.setType(oldArticle.getType());
551 newArticle.setStructureId(oldArticle.getStructureId());
552 newArticle.setTemplateId(oldArticle.getTemplateId());
553 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
554 newArticle.setDisplayDate(oldArticle.getDisplayDate());
555 newArticle.setExpirationDate(oldArticle.getExpirationDate());
556 newArticle.setReviewDate(oldArticle.getReviewDate());
557 newArticle.setIndexable(oldArticle.isIndexable());
558 newArticle.setSmallImage(oldArticle.isSmallImage());
559 newArticle.setSmallImageId(counterLocalService.increment());
560 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
561 newArticle.setStatus(oldArticle.getStatus());
562
563 journalArticlePersistence.update(newArticle, false);
564
565
566
567 addArticleResources(newArticle, true, true);
568
569
570
571 if (oldArticle.getSmallImage()) {
572 Image image = imageLocalService.getImage(
573 oldArticle.getSmallImageId());
574
575 byte[] smallImageBytes = image.getTextObj();
576
577 imageLocalService.updateImage(
578 newArticle.getSmallImageId(), smallImageBytes);
579 }
580
581
582
583 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
584 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
585 String[] assetTagNames = assetTagLocalService.getTagNames(
586 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
587
588 updateAsset(userId, newArticle, assetCategoryIds, assetTagNames, null);
589
590 return newArticle;
591 }
592
593 public void deleteArticle(
594 JournalArticle article, String articleURL,
595 ServiceContext serviceContext)
596 throws PortalException, SystemException {
597
598 if (article.isApproved() &&
599 isLatestVersion(
600 article.getGroupId(), article.getArticleId(),
601 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
602
603 updatePreviousApprovedArticle(article);
604 }
605
606
607
608 PortletPreferences preferences =
609 ServiceContextUtil.getPortletPreferences(serviceContext);
610
611 if ((preferences != null) && !article.isApproved() &&
612 isLatestVersion(
613 article.getGroupId(), article.getArticleId(),
614 article.getVersion())) {
615
616 sendEmail(article, articleURL, preferences, "denied");
617 }
618
619
620
621 journalArticleImageLocalService.deleteImages(
622 article.getGroupId(), article.getArticleId(), article.getVersion());
623
624
625
626 if (!article.isDraft()) {
627 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
628 article.getCompanyId(), article.getGroupId(),
629 JournalArticle.class.getName(), article.getId());
630 }
631
632 int articlesCount = journalArticlePersistence.countByG_A(
633 article.getGroupId(), article.getArticleId());
634
635 if (articlesCount == 1) {
636
637
638
639 ratingsStatsLocalService.deleteStats(
640 JournalArticle.class.getName(), article.getResourcePrimKey());
641
642
643
644 mbMessageLocalService.deleteDiscussionMessages(
645 JournalArticle.class.getName(), article.getResourcePrimKey());
646
647
648
649 assetEntryLocalService.deleteEntry(
650 JournalArticle.class.getName(), article.getResourcePrimKey());
651
652
653
654 journalContentSearchLocalService.deleteArticleContentSearches(
655 article.getGroupId(), article.getArticleId());
656
657
658
659 imageLocalService.deleteImage(article.getSmallImageId());
660
661
662
663 expandoValueLocalService.deleteValues(
664 JournalArticle.class.getName(), article.getResourcePrimKey());
665
666
667
668 resourceLocalService.deleteResource(
669 article.getCompanyId(), JournalArticle.class.getName(),
670 ResourceConstants.SCOPE_INDIVIDUAL,
671 article.getResourcePrimKey());
672
673
674
675 try {
676 journalArticleResourceLocalService.deleteArticleResource(
677 article.getGroupId(), article.getArticleId());
678 }
679 catch (NoSuchArticleResourceException nsare) {
680 }
681 }
682
683
684
685 journalArticlePersistence.remove(article);
686 }
687
688 public void deleteArticle(
689 long groupId, String articleId, double version, String articleURL,
690 ServiceContext serviceContext)
691 throws PortalException, SystemException {
692
693 JournalArticle article = journalArticlePersistence.findByG_A_V(
694 groupId, articleId, version);
695
696 deleteArticle(article, articleURL, serviceContext);
697 }
698
699 public void deleteArticle(
700 long groupId, String articleId, ServiceContext serviceContext)
701 throws PortalException, SystemException {
702
703 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
704 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
705 new ArticleVersionComparator(true));
706
707 for (JournalArticle article : articles) {
708 deleteArticle(article, null, serviceContext);
709 }
710 }
711
712 public void deleteArticles(long groupId)
713 throws PortalException, SystemException {
714
715 for (JournalArticle article :
716 journalArticlePersistence.findByGroupId(groupId)) {
717
718 deleteArticle(article, null, null);
719 }
720 }
721
722 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
723 throws SystemException {
724
725 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
726 groupId, layoutUuid);
727
728 for (JournalArticle article: articles) {
729 article.setLayoutUuid(StringPool.BLANK);
730
731 journalArticlePersistence.update(article, false);
732 }
733 }
734
735 public JournalArticle expireArticle(
736 long userId, long groupId, String articleId, double version,
737 String articleURL, ServiceContext serviceContext)
738 throws PortalException, SystemException {
739
740 return updateStatus(
741 userId, groupId, articleId, version,
742 WorkflowConstants.STATUS_EXPIRED, articleURL, serviceContext);
743 }
744
745 public void expireArticle(
746 long userId, long groupId, String articleId, String articleURL,
747 ServiceContext serviceContext)
748 throws PortalException, SystemException {
749
750 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
751 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
752 new ArticleVersionComparator(true));
753
754 for (JournalArticle article : articles) {
755 expireArticle(
756 userId, groupId, article.getArticleId(), article.getVersion(),
757 articleURL, serviceContext);
758 }
759 }
760
761 public JournalArticle getArticle(long id)
762 throws PortalException, SystemException {
763
764 return journalArticlePersistence.findByPrimaryKey(id);
765 }
766
767 public JournalArticle getArticle(long groupId, String articleId)
768 throws PortalException, SystemException {
769
770
771
772
773 try {
774 return getLatestArticle(
775 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
776 }
777 catch (NoSuchArticleException nsae) {
778 return getLatestArticle(
779 groupId, articleId, WorkflowConstants.STATUS_ANY);
780 }
781 }
782
783 public JournalArticle getArticle(
784 long groupId, String articleId, double version)
785 throws PortalException, SystemException {
786
787 return journalArticlePersistence.findByG_A_V(
788 groupId, articleId, version);
789 }
790
791 public JournalArticle getArticle(
792 long groupId, String className, long classPK)
793 throws PortalException, SystemException {
794
795 long classNameId = PortalUtil.getClassNameId(className);
796
797 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
798 groupId, classNameId, classPK);
799
800 if (articles.isEmpty()) {
801 throw new NoSuchArticleException(
802 "No approved JournalArticle with the key {groupId=" + groupId +
803 ", className=" + className + ", classPK=" + classPK + "}");
804 }
805
806 return articles.get(0);
807 }
808
809 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
810 throws PortalException, SystemException {
811
812
813
814
815 try {
816 return getLatestArticleByUrlTitle(
817 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
818 }
819 catch (NoSuchArticleException nsae) {
820 return getLatestArticleByUrlTitle(
821 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
822 }
823 }
824
825 public String getArticleContent(
826 JournalArticle article, String templateId, String viewMode,
827 String languageId, ThemeDisplay themeDisplay)
828 throws PortalException, SystemException {
829
830 JournalArticleDisplay articleDisplay = getArticleDisplay(
831 article, templateId, viewMode, languageId, 1, null, themeDisplay);
832
833 if (articleDisplay == null) {
834 return StringPool.BLANK;
835 }
836 else {
837 return articleDisplay.getContent();
838 }
839 }
840
841 public String getArticleContent(
842 long groupId, String articleId, double version, String viewMode,
843 String templateId, String languageId, ThemeDisplay themeDisplay)
844 throws PortalException, SystemException {
845
846 JournalArticleDisplay articleDisplay = getArticleDisplay(
847 groupId, articleId, version, templateId, viewMode, languageId,
848 themeDisplay);
849
850 if (articleDisplay == null) {
851 return StringPool.BLANK;
852 }
853 else {
854 return articleDisplay.getContent();
855 }
856 }
857
858 public String getArticleContent(
859 long groupId, String articleId, double version, String viewMode,
860 String languageId, ThemeDisplay themeDisplay)
861 throws PortalException, SystemException {
862
863 return getArticleContent(
864 groupId, articleId, version, viewMode, null, languageId,
865 themeDisplay);
866 }
867
868 public String getArticleContent(
869 long groupId, String articleId, String viewMode, String templateId,
870 String languageId, ThemeDisplay themeDisplay)
871 throws PortalException, SystemException {
872
873 JournalArticleDisplay articleDisplay = getArticleDisplay(
874 groupId, articleId, templateId, viewMode, languageId, themeDisplay);
875
876 return articleDisplay.getContent();
877 }
878
879 public String getArticleContent(
880 long groupId, String articleId, String viewMode, String languageId,
881 ThemeDisplay themeDisplay)
882 throws PortalException, SystemException {
883
884 return getArticleContent(
885 groupId, articleId, viewMode, null, languageId, themeDisplay);
886 }
887
888 public JournalArticleDisplay getArticleDisplay(
889 JournalArticle article, String templateId, String viewMode,
890 String languageId, int page, String xmlRequest,
891 ThemeDisplay themeDisplay)
892 throws PortalException, SystemException {
893
894 String content = null;
895
896 if (page < 1) {
897 page = 1;
898 }
899
900 int numberOfPages = 1;
901 boolean paginate = false;
902 boolean pageFlow = false;
903
904 boolean cacheable = true;
905
906 if (Validator.isNull(xmlRequest)) {
907 xmlRequest = "<request />";
908 }
909
910 Map<String, String> tokens = JournalUtil.getTokens(
911 article.getGroupId(), themeDisplay, xmlRequest);
912
913 tokens.put(
914 "article_resource_pk",
915 String.valueOf(article.getResourcePrimKey()));
916
917 String defaultTemplateId = article.getTemplateId();
918
919 if (article.isTemplateDriven()) {
920 if (Validator.isNull(templateId)) {
921 templateId = defaultTemplateId;
922 }
923
924 tokens.put("structure_id", article.getStructureId());
925 tokens.put("template_id", templateId);
926 }
927
928 String xml = article.getContent();
929
930 try {
931 Document document = null;
932
933 Element rootElement = null;
934
935 if (article.isTemplateDriven()) {
936 document = SAXReaderUtil.read(xml);
937
938 rootElement = document.getRootElement();
939
940 Document requestDocument = SAXReaderUtil.read(xmlRequest);
941
942 List<Element> pages = rootElement.elements("page");
943
944 if (!pages.isEmpty()) {
945 pageFlow = true;
946
947 String targetPage = requestDocument.valueOf(
948 "/request/parameters/parameter[name='targetPage']/" +
949 "value");
950
951 Element pageElement = null;
952
953 if (Validator.isNotNull(targetPage)) {
954 XPath xpathSelector = SAXReaderUtil.createXPath(
955 "/root/page[@id = '" + targetPage + "']");
956
957 pageElement = (Element)xpathSelector.selectSingleNode(
958 document);
959 }
960
961 if (pageElement != null) {
962 document = SAXReaderUtil.createDocument(pageElement);
963
964 rootElement = document.getRootElement();
965
966 numberOfPages = pages.size();
967 }
968 else {
969 if (page > pages.size()) {
970 page = 1;
971 }
972
973 pageElement = pages.get(page - 1);
974
975 document = SAXReaderUtil.createDocument(pageElement);
976
977 rootElement = document.getRootElement();
978
979 numberOfPages = pages.size();
980 paginate = true;
981 }
982 }
983
984 rootElement.add(requestDocument.getRootElement().createCopy());
985
986 JournalUtil.addAllReservedEls(rootElement, tokens, article);
987
988 xml = DDMXMLUtil.formatXML(document);
989 }
990 }
991 catch (DocumentException de) {
992 throw new SystemException(de);
993 }
994 catch (IOException ioe) {
995 throw new SystemException(ioe);
996 }
997
998 try {
999 if (_log.isDebugEnabled()) {
1000 _log.debug(
1001 "Transforming " + article.getArticleId() + " " +
1002 article.getVersion() + " " + languageId);
1003 }
1004
1005 String script = null;
1006 String langType = null;
1007
1008 if (article.isTemplateDriven()) {
1009
1010
1011
1012
1013
1014
1015
1016 JournalTemplate template = null;
1017
1018 try {
1019 template = journalTemplatePersistence.findByG_T(
1020 article.getGroupId(), templateId);
1021 }
1022 catch (NoSuchTemplateException nste1) {
1023 try {
1024 Group companyGroup = groupLocalService.getCompanyGroup(
1025 article.getCompanyId());
1026
1027 template = journalTemplatePersistence.findByG_T(
1028 companyGroup.getGroupId(), templateId);
1029
1030 tokens.put(
1031 "company_group_id",
1032 String.valueOf(companyGroup.getGroupId()));
1033 }
1034 catch (NoSuchTemplateException nste2) {
1035 if (!defaultTemplateId.equals(templateId)) {
1036 template = journalTemplatePersistence.findByG_T(
1037 article.getGroupId(), defaultTemplateId);
1038 }
1039 else {
1040 throw nste1;
1041 }
1042 }
1043 }
1044
1045 script = template.getXsl();
1046 langType = template.getLangType();
1047 cacheable = template.isCacheable();
1048 }
1049
1050 content = JournalUtil.transform(
1051 themeDisplay, tokens, viewMode, languageId, xml, script,
1052 langType);
1053
1054 if (!pageFlow) {
1055 String[] pieces = StringUtil.split(
1056 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1057
1058 if (pieces.length > 1) {
1059 if (page > pieces.length) {
1060 page = 1;
1061 }
1062
1063 content = pieces[page - 1];
1064 numberOfPages = pieces.length;
1065 paginate = true;
1066 }
1067 }
1068 }
1069 catch (Exception e) {
1070 throw new SystemException(e);
1071 }
1072
1073 return new JournalArticleDisplayImpl(
1074 article.getCompanyId(), article.getId(),
1075 article.getResourcePrimKey(), article.getGroupId(),
1076 article.getUserId(), article.getArticleId(), article.getVersion(),
1077 article.getTitle(languageId), article.getUrlTitle(),
1078 article.getDescription(languageId), article.getAvailableLocales(),
1079 content, article.getType(), article.getStructureId(), templateId,
1080 article.isSmallImage(), article.getSmallImageId(),
1081 article.getSmallImageURL(), numberOfPages, page, paginate,
1082 cacheable);
1083 }
1084
1085 public JournalArticleDisplay getArticleDisplay(
1086 long groupId, String articleId, double version, String templateId,
1087 String viewMode, String languageId, int page, String xmlRequest,
1088 ThemeDisplay themeDisplay)
1089 throws PortalException, SystemException {
1090
1091 Date now = new Date();
1092
1093 JournalArticle article = journalArticlePersistence.findByG_A_V(
1094 groupId, articleId, version);
1095
1096 if (article.isExpired()) {
1097 Date expirationDate = article.getExpirationDate();
1098
1099 if ((expirationDate != null) && expirationDate.before(now)) {
1100 return null;
1101 }
1102 }
1103
1104 if (article.getDisplayDate().after(now)) {
1105 return null;
1106 }
1107
1108 return getArticleDisplay(
1109 article, templateId, viewMode, languageId, page, xmlRequest,
1110 themeDisplay);
1111 }
1112
1113 public JournalArticleDisplay getArticleDisplay(
1114 long groupId, String articleId, double version, String templateId,
1115 String viewMode, String languageId, ThemeDisplay themeDisplay)
1116 throws PortalException, SystemException {
1117
1118 return getArticleDisplay(
1119 groupId, articleId, version, templateId, viewMode, languageId, 1,
1120 null, themeDisplay);
1121 }
1122
1123 public JournalArticleDisplay getArticleDisplay(
1124 long groupId, String articleId, String viewMode, String languageId,
1125 int page, String xmlRequest, ThemeDisplay themeDisplay)
1126 throws PortalException, SystemException {
1127
1128 return getArticleDisplay(
1129 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
1130 themeDisplay);
1131 }
1132
1133 public JournalArticleDisplay getArticleDisplay(
1134 long groupId, String articleId, String templateId, String viewMode,
1135 String languageId, int page, String xmlRequest,
1136 ThemeDisplay themeDisplay)
1137 throws PortalException, SystemException {
1138
1139 JournalArticle article = getDisplayArticle(groupId, articleId);
1140
1141 return getArticleDisplay(
1142 groupId, articleId, article.getVersion(), templateId, viewMode,
1143 languageId, page, xmlRequest, themeDisplay);
1144 }
1145
1146 public JournalArticleDisplay getArticleDisplay(
1147 long groupId, String articleId, String templateId, String viewMode,
1148 String languageId, ThemeDisplay themeDisplay)
1149 throws PortalException, SystemException {
1150
1151 JournalArticle article = getDisplayArticle(groupId, articleId);
1152
1153 return getArticleDisplay(
1154 groupId, articleId, article.getVersion(), templateId, viewMode,
1155 languageId, themeDisplay);
1156 }
1157
1158 public JournalArticleDisplay getArticleDisplay(
1159 long groupId, String articleId, String viewMode, String languageId,
1160 ThemeDisplay themeDisplay)
1161 throws PortalException, SystemException {
1162
1163 return getArticleDisplay(
1164 groupId, articleId, null, viewMode, languageId, themeDisplay);
1165 }
1166
1167 public List<JournalArticle> getArticles() throws SystemException {
1168 return journalArticlePersistence.findAll();
1169 }
1170
1171 public List<JournalArticle> getArticles(long groupId)
1172 throws SystemException {
1173
1174 return journalArticlePersistence.findByGroupId(groupId);
1175 }
1176
1177 public List<JournalArticle> getArticles(long groupId, int start, int end)
1178 throws SystemException {
1179
1180 return journalArticlePersistence.findByGroupId(groupId, start, end);
1181 }
1182
1183 public List<JournalArticle> getArticles(
1184 long groupId, int start, int end, OrderByComparator obc)
1185 throws SystemException {
1186
1187 return journalArticlePersistence.findByGroupId(
1188 groupId, start, end, obc);
1189 }
1190
1191 public List<JournalArticle> getArticles(long groupId, String articleId)
1192 throws SystemException {
1193
1194 return journalArticlePersistence.findByG_A(groupId, articleId);
1195 }
1196
1197 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
1198 throws SystemException {
1199
1200 return journalArticlePersistence.findBySmallImageId(smallImageId);
1201 }
1202
1203 public int getArticlesCount(long groupId) throws SystemException {
1204 return journalArticlePersistence.countByGroupId(groupId);
1205 }
1206
1207 public List<JournalArticle> getCompanyArticles(
1208 long companyId, double version, int status, int start, int end)
1209 throws SystemException {
1210
1211 if (status == WorkflowConstants.STATUS_ANY) {
1212 return journalArticlePersistence.findByC_V(
1213 companyId, version, start, end, new ArticleIDComparator(true));
1214 }
1215 else {
1216 return journalArticlePersistence.findByC_V_ST(
1217 companyId, version, status, start, end,
1218 new ArticleIDComparator(true));
1219 }
1220 }
1221
1222 public List<JournalArticle> getCompanyArticles(
1223 long companyId, int status, int start, int end)
1224 throws SystemException {
1225
1226 if (status == WorkflowConstants.STATUS_ANY) {
1227 return journalArticlePersistence.findByCompanyId(
1228 companyId, start, end, new ArticleIDComparator(true));
1229 }
1230 else {
1231 return journalArticlePersistence.findByC_ST(
1232 companyId, status, start, end, new ArticleIDComparator(true));
1233 }
1234 }
1235
1236 public int getCompanyArticlesCount(
1237 long companyId, double version, int status, int start, int end)
1238 throws SystemException {
1239
1240 if (status == WorkflowConstants.STATUS_ANY) {
1241 return journalArticlePersistence.countByC_V(companyId, version);
1242 }
1243 else {
1244 return journalArticlePersistence.countByC_V_ST(
1245 companyId, version, status);
1246 }
1247 }
1248
1249 public int getCompanyArticlesCount(long companyId, int status)
1250 throws SystemException {
1251
1252 if (status == WorkflowConstants.STATUS_ANY) {
1253 return journalArticlePersistence.countByCompanyId(companyId);
1254 }
1255 else {
1256 return journalArticlePersistence.countByC_ST(companyId, status);
1257 }
1258 }
1259
1260 public JournalArticle getDisplayArticle(long groupId, String articleId)
1261 throws PortalException, SystemException {
1262
1263 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
1264 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1265
1266 if (articles.isEmpty()) {
1267 throw new NoSuchArticleException(
1268 "No approved JournalArticle with the key {groupId=" + groupId +
1269 ", " + "articleId=" + articleId + "}");
1270
1271 }
1272
1273 Date now = new Date();
1274
1275 for (int i = 0; i < articles.size(); i++) {
1276 JournalArticle article = articles.get(i);
1277
1278 Date expirationDate = article.getExpirationDate();
1279
1280 if (article.getDisplayDate().before(now) &&
1281 ((expirationDate == null) || expirationDate.after(now))) {
1282
1283 return article;
1284 }
1285 }
1286
1287 return articles.get(0);
1288 }
1289
1290 public JournalArticle getLatestArticle(long resourcePrimKey)
1291 throws PortalException, SystemException {
1292
1293 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
1294 }
1295
1296 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
1297 throws PortalException, SystemException {
1298
1299 return getLatestArticle(resourcePrimKey, status, true);
1300 }
1301
1302 public JournalArticle getLatestArticle(
1303 long resourcePrimKey, int status, boolean preferApproved)
1304 throws PortalException, SystemException {
1305
1306 List<JournalArticle> articles = null;
1307
1308 OrderByComparator orderByComparator = new ArticleVersionComparator();
1309
1310 if (status == WorkflowConstants.STATUS_ANY) {
1311 if (preferApproved) {
1312 articles = journalArticlePersistence.findByR_ST(
1313 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
1314 orderByComparator);
1315 }
1316
1317 if ((articles == null) || (articles.size() == 0)) {
1318 articles = journalArticlePersistence.findByResourcePrimKey(
1319 resourcePrimKey, 0, 1, orderByComparator);
1320 }
1321 }
1322 else {
1323 articles = journalArticlePersistence.findByR_ST(
1324 resourcePrimKey, status, 0, 1, orderByComparator);
1325 }
1326
1327 if (articles.isEmpty()) {
1328 throw new NoSuchArticleException(
1329 "No JournalArticle with the key {resourcePrimKey=" +
1330 resourcePrimKey + "}");
1331 }
1332
1333 return articles.get(0);
1334 }
1335
1336 public JournalArticle getLatestArticle(long groupId, String articleId)
1337 throws PortalException, SystemException {
1338
1339 return getLatestArticle(
1340 groupId, articleId, WorkflowConstants.STATUS_ANY);
1341 }
1342
1343 public JournalArticle getLatestArticle(
1344 long groupId, String articleId, int status)
1345 throws PortalException, SystemException {
1346
1347 List<JournalArticle> articles = null;
1348
1349 OrderByComparator orderByComparator = new ArticleVersionComparator();
1350
1351 if (status == WorkflowConstants.STATUS_ANY) {
1352 articles = journalArticlePersistence.findByG_A(
1353 groupId, articleId, 0, 1, orderByComparator);
1354 }
1355 else {
1356 articles = journalArticlePersistence.findByG_A_ST(
1357 groupId, articleId, status, 0, 1, orderByComparator);
1358 }
1359
1360 if (articles.isEmpty()) {
1361 throw new NoSuchArticleException(
1362 "No JournalArticle with the key {groupId=" + groupId +
1363 ", articleId=" + articleId + ", status=" + status + "}");
1364 }
1365
1366 return articles.get(0);
1367 }
1368
1369 public JournalArticle getLatestArticle(
1370 long groupId, String className, long classPK)
1371 throws PortalException, SystemException {
1372
1373 long classNameId = PortalUtil.getClassNameId(className);
1374
1375 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1376 groupId, classNameId, classPK, 0, 1,
1377 new ArticleVersionComparator());
1378
1379 if (articles.isEmpty()) {
1380 throw new NoSuchArticleException(
1381 "No JournalArticle with the key {groupId=" + groupId +
1382 ", className=" + className + ", classPK =" + classPK + "}");
1383 }
1384
1385 return articles.get(0);
1386 }
1387
1388 public JournalArticle getLatestArticleByUrlTitle(
1389 long groupId, String urlTitle, int status)
1390 throws PortalException, SystemException {
1391
1392 List<JournalArticle> articles = null;
1393
1394 OrderByComparator orderByComparator = new ArticleVersionComparator();
1395
1396 if (status == WorkflowConstants.STATUS_ANY) {
1397 articles = journalArticlePersistence.findByG_UT(
1398 groupId, urlTitle, 0, 1, orderByComparator);
1399 }
1400 else {
1401 articles = journalArticlePersistence.findByG_UT_ST(
1402 groupId, urlTitle, status, 0, 1, orderByComparator);
1403 }
1404
1405 if (articles.isEmpty()) {
1406 throw new NoSuchArticleException(
1407 "No JournalArticle with the key {groupId=" + groupId +
1408 ", urlTitle=" + urlTitle + ", status=" + status + "}");
1409 }
1410
1411 return articles.get(0);
1412 }
1413
1414 public double getLatestVersion(long groupId, String articleId)
1415 throws PortalException, SystemException {
1416
1417 JournalArticle article = getLatestArticle(groupId, articleId);
1418
1419 return article.getVersion();
1420 }
1421
1422 public double getLatestVersion(
1423 long groupId, String articleId, int status)
1424 throws PortalException, SystemException {
1425
1426 JournalArticle article = getLatestArticle(groupId, articleId, status);
1427
1428 return article.getVersion();
1429 }
1430
1431 public List<JournalArticle> getStructureArticles(
1432 long groupId, String structureId)
1433 throws SystemException {
1434
1435 return journalArticlePersistence.findByG_S(groupId, structureId);
1436 }
1437
1438 public List<JournalArticle> getStructureArticles(
1439 long groupId, String structureId, int start, int end,
1440 OrderByComparator obc)
1441 throws SystemException {
1442
1443 return journalArticlePersistence.findByG_S(
1444 groupId, structureId, start, end, obc);
1445 }
1446
1447 public int getStructureArticlesCount(long groupId, String structureId)
1448 throws SystemException {
1449
1450 return journalArticlePersistence.countByG_S(groupId, structureId);
1451 }
1452
1453 public List<JournalArticle> getTemplateArticles(
1454 long groupId, String templateId)
1455 throws SystemException {
1456
1457 return journalArticlePersistence.findByG_T(groupId, templateId);
1458 }
1459
1460 public List<JournalArticle> getTemplateArticles(
1461 long groupId, String templateId, int start, int end,
1462 OrderByComparator obc)
1463 throws SystemException {
1464
1465 return journalArticlePersistence.findByG_T(
1466 groupId, templateId, start, end, obc);
1467 }
1468
1469 public int getTemplateArticlesCount(long groupId, String templateId)
1470 throws SystemException {
1471
1472 return journalArticlePersistence.countByG_T(groupId, templateId);
1473 }
1474
1475 public boolean hasArticle(long groupId, String articleId)
1476 throws SystemException {
1477
1478 try {
1479 getArticle(groupId, articleId);
1480
1481 return true;
1482 }
1483 catch (PortalException pe) {
1484 return false;
1485 }
1486 }
1487
1488 public boolean isLatestVersion(
1489 long groupId, String articleId, double version)
1490 throws PortalException, SystemException {
1491
1492 if (getLatestVersion(groupId, articleId) == version) {
1493 return true;
1494 }
1495 else {
1496 return false;
1497 }
1498 }
1499
1500 public boolean isLatestVersion(
1501 long groupId, String articleId, double version, int status)
1502 throws PortalException, SystemException {
1503
1504 if (getLatestVersion(groupId, articleId, status) == version) {
1505 return true;
1506 }
1507 else {
1508 return false;
1509 }
1510 }
1511
1512 public JournalArticle removeArticleLocale(
1513 long groupId, String articleId, double version, String languageId)
1514 throws PortalException, SystemException {
1515
1516 JournalArticle article = journalArticlePersistence.findByG_A_V(
1517 groupId, articleId, version);
1518
1519 String title = article.getTitle();
1520
1521 title = LocalizationUtil.removeLocalization(
1522 title, "static-content", languageId, true);
1523
1524 article.setTitle(title);
1525
1526 String description = article.getDescription();
1527
1528 description = LocalizationUtil.removeLocalization(
1529 description, "static-content", languageId, true);
1530
1531 article.setDescription(description);
1532
1533 String content = article.getContent();
1534
1535 if (article.isTemplateDriven()) {
1536 content = JournalUtil.removeArticleLocale(content, languageId);
1537 }
1538 else {
1539 content = LocalizationUtil.removeLocalization(
1540 content, "static-content", languageId, true);
1541 }
1542
1543 article.setContent(content);
1544
1545 journalArticlePersistence.update(article, false);
1546
1547 return article;
1548 }
1549
1550 public List<JournalArticle> search(
1551 long companyId, long groupId, long classNameId, String keywords,
1552 Double version, String type, String structureId, String templateId,
1553 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1554 int start, int end, OrderByComparator obc)
1555 throws SystemException {
1556
1557 return journalArticleFinder.findByKeywords(
1558 companyId, groupId, classNameId, keywords, version, type,
1559 structureId, templateId, displayDateGT, displayDateLT, status,
1560 reviewDate, start, end, obc);
1561 }
1562
1563 public List<JournalArticle> search(
1564 long companyId, long groupId, long classNameId, String articleId,
1565 Double version, String title, String description, String content,
1566 String type, String structureId, String templateId,
1567 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1568 boolean andOperator, int start, int end, OrderByComparator obc)
1569 throws SystemException {
1570
1571 return journalArticleFinder.findByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1572 companyId, groupId, classNameId, articleId, version, title,
1573 description, content, type, structureId, templateId, displayDateGT,
1574 displayDateLT, status, reviewDate, andOperator, start, end, obc);
1575 }
1576
1577 public List<JournalArticle> search(
1578 long companyId, long groupId, long classNameId, String articleId,
1579 Double version, String title, String description, String content,
1580 String type, String[] structureIds, String[] templateIds,
1581 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1582 boolean andOperator, int start, int end, OrderByComparator obc)
1583 throws SystemException {
1584
1585 return journalArticleFinder.findByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1586 companyId, groupId, classNameId, articleId, version, title,
1587 description, content, type, structureIds, templateIds,
1588 displayDateGT, displayDateLT, status, reviewDate, andOperator,
1589 start, end, obc);
1590 }
1591
1592 public Hits search(
1593 long companyId, long groupId, long classNameId, String structureId,
1594 String templateId, String keywords,
1595 LinkedHashMap<String, Object> params, int start, int end, Sort sort)
1596 throws SystemException {
1597
1598 String articleId = null;
1599 String title = null;
1600 String description = null;
1601 String content = null;
1602 boolean andOperator = false;
1603
1604 if (Validator.isNotNull(keywords)) {
1605 articleId = keywords;
1606 title = keywords;
1607 description = keywords;
1608 content = keywords;
1609 }
1610 else {
1611 andOperator = true;
1612 }
1613
1614 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
1615
1616 return search(
1617 companyId, groupId, classNameId, articleId, title, description,
1618 content, null, status, structureId, templateId, params, andOperator,
1619 start, end, sort);
1620 }
1621
1622 public Hits search(
1623 long companyId, long groupId, long classNameId, String articleId,
1624 String title, String description, String content, String type,
1625 String status, String structureId, String templateId,
1626 LinkedHashMap<String, Object> params, boolean andSearch, int start,
1627 int end, Sort sort)
1628 throws SystemException {
1629
1630 try {
1631 Map<String, Serializable> attributes =
1632 new HashMap<String, Serializable>();
1633
1634 attributes.put(Field.CLASS_NAME_ID, classNameId);
1635 attributes.put(Field.CONTENT, content);
1636 attributes.put(Field.DESCRIPTION, description);
1637 attributes.put(Field.STATUS, status);
1638 attributes.put(Field.TITLE, title);
1639 attributes.put(Field.TYPE, type);
1640 attributes.put("articleId", articleId);
1641 attributes.put("params", params);
1642 attributes.put("structureId", structureId);
1643 attributes.put("templateId", templateId);
1644
1645 SearchContext searchContext = new SearchContext();
1646
1647 searchContext.setAndSearch(andSearch);
1648 searchContext.setAttributes(attributes);
1649 searchContext.setCompanyId(companyId);
1650 searchContext.setGroupIds(new long[] {groupId});
1651 searchContext.setEnd(end);
1652 searchContext.setSorts(new Sort[] {sort});
1653
1654 QueryConfig queryConfig = new QueryConfig();
1655
1656 queryConfig.setHighlightEnabled(false);
1657 queryConfig.setScoreEnabled(false);
1658
1659 searchContext.setQueryConfig(queryConfig);
1660
1661 searchContext.setStart(start);
1662
1663 Indexer indexer = IndexerRegistryUtil.getIndexer(
1664 JournalArticle.class);
1665
1666 return indexer.search(searchContext);
1667 }
1668 catch (Exception e) {
1669 throw new SystemException(e);
1670 }
1671 }
1672
1673 public int searchCount(
1674 long companyId, long groupId, long classNameId, String keywords,
1675 Double version, String type, String structureId, String templateId,
1676 Date displayDateGT, Date displayDateLT, int status, Date reviewDate)
1677 throws SystemException {
1678
1679 return journalArticleFinder.countByKeywords(
1680 companyId, groupId, classNameId, keywords, version, type,
1681 structureId, templateId, displayDateGT, displayDateLT, status,
1682 reviewDate);
1683 }
1684
1685 public int searchCount(
1686 long companyId, long groupId, long classNameId, String articleId,
1687 Double version, String title, String description, String content,
1688 String type, String structureId, String templateId,
1689 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1690 boolean andOperator)
1691 throws SystemException {
1692
1693 return journalArticleFinder.countByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1694 companyId, groupId, classNameId, articleId, version, title,
1695 description, content, type, structureId, templateId, displayDateGT,
1696 displayDateLT, status, reviewDate, andOperator);
1697 }
1698
1699 public int searchCount(
1700 long companyId, long groupId, long classNameId, String articleId,
1701 Double version, String title, String description, String content,
1702 String type, String[] structureIds, String[] templateIds,
1703 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
1704 boolean andOperator)
1705 throws SystemException {
1706
1707 return journalArticleFinder.countByC_G_C_A_V_T_D_C_T_S_T_D_S_R(
1708 companyId, groupId, classNameId, articleId, version, title,
1709 description, content, type, structureIds, templateIds,
1710 displayDateGT, displayDateLT, status, reviewDate, andOperator);
1711 }
1712
1713 public void subscribe(long userId, long groupId)
1714 throws PortalException, SystemException {
1715
1716 subscriptionLocalService.addSubscription(
1717 userId, groupId, JournalArticle.class.getName(), groupId);
1718 }
1719
1720 public void unsubscribe(long userId, long groupId)
1721 throws PortalException, SystemException {
1722
1723 subscriptionLocalService.deleteSubscription(
1724 userId, JournalArticle.class.getName(), groupId);
1725 }
1726
1727 public JournalArticle updateArticle(
1728 long userId, long groupId, String articleId, double version,
1729 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
1730 String content, String layoutUuid, ServiceContext serviceContext)
1731 throws PortalException, SystemException {
1732
1733 User user = userPersistence.findByPrimaryKey(userId);
1734
1735 JournalArticle article = journalArticlePersistence.findByG_A_V(
1736 groupId, articleId, version);
1737
1738 Date displayDate = article.getDisplayDate();
1739
1740 int displayDateMonth = 0;
1741 int displayDateDay = 0;
1742 int displayDateYear = 0;
1743 int displayDateHour = 0;
1744 int displayDateMinute = 0;
1745
1746 if (displayDate != null) {
1747 Calendar displayCal = CalendarFactoryUtil.getCalendar(
1748 user.getTimeZone());
1749
1750 displayCal.setTime(displayDate);
1751
1752 displayDateMonth = displayCal.get(Calendar.MONTH);
1753 displayDateDay = displayCal.get(Calendar.DATE);
1754 displayDateYear = displayCal.get(Calendar.YEAR);
1755 displayDateHour = displayCal.get(Calendar.HOUR);
1756 displayDateMinute = displayCal.get(Calendar.MINUTE);
1757
1758 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
1759 displayDateHour += 12;
1760 }
1761 }
1762
1763 Date expirationDate = article.getExpirationDate();
1764
1765 int expirationDateMonth = 0;
1766 int expirationDateDay = 0;
1767 int expirationDateYear = 0;
1768 int expirationDateHour = 0;
1769 int expirationDateMinute = 0;
1770 boolean neverExpire = true;
1771
1772 if (expirationDate != null) {
1773 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
1774 user.getTimeZone());
1775
1776 expirationCal.setTime(expirationDate);
1777
1778 expirationDateMonth = expirationCal.get(Calendar.MONTH);
1779 expirationDateDay = expirationCal.get(Calendar.DATE);
1780 expirationDateYear = expirationCal.get(Calendar.YEAR);
1781 expirationDateHour = expirationCal.get(Calendar.HOUR);
1782 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
1783 neverExpire = false;
1784
1785 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
1786 expirationDateHour += 12;
1787 }
1788 }
1789
1790 Date reviewDate = article.getReviewDate();
1791
1792 int reviewDateMonth = 0;
1793 int reviewDateDay = 0;
1794 int reviewDateYear = 0;
1795 int reviewDateHour = 0;
1796 int reviewDateMinute = 0;
1797 boolean neverReview = true;
1798
1799 if (reviewDate != null) {
1800 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
1801 user.getTimeZone());
1802
1803 reviewCal.setTime(reviewDate);
1804
1805 reviewDateMonth = reviewCal.get(Calendar.MONTH);
1806 reviewDateDay = reviewCal.get(Calendar.DATE);
1807 reviewDateYear = reviewCal.get(Calendar.YEAR);
1808 reviewDateHour = reviewCal.get(Calendar.HOUR);
1809 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
1810 neverReview = false;
1811
1812 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
1813 reviewDateHour += 12;
1814 }
1815 }
1816
1817 return updateArticle(
1818 userId, groupId, articleId, version, titleMap, descriptionMap,
1819 content, article.getType(), article.getStructureId(),
1820 article.getTemplateId(), layoutUuid, displayDateMonth,
1821 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
1822 expirationDateMonth, expirationDateDay, expirationDateYear,
1823 expirationDateHour, expirationDateMinute, neverExpire,
1824 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
1825 reviewDateMinute, neverReview, article.getIndexable(),
1826 article.isSmallImage(), article.getSmallImageURL(), null, null,
1827 null, serviceContext);
1828 }
1829
1830 public JournalArticle updateArticle(
1831 long userId, long groupId, String articleId, double version,
1832 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
1833 String content, String type, String structureId, String templateId,
1834 String layoutUuid, int displayDateMonth, int displayDateDay,
1835 int displayDateYear, int displayDateHour, int displayDateMinute,
1836 int expirationDateMonth, int expirationDateDay,
1837 int expirationDateYear, int expirationDateHour,
1838 int expirationDateMinute, boolean neverExpire, int reviewDateMonth,
1839 int reviewDateDay, int reviewDateYear, int reviewDateHour,
1840 int reviewDateMinute, boolean neverReview, boolean indexable,
1841 boolean smallImage, String smallImageURL, File smallImageFile,
1842 Map<String, byte[]> images, String articleURL,
1843 ServiceContext serviceContext)
1844 throws PortalException, SystemException {
1845
1846
1847
1848 User user = userPersistence.findByPrimaryKey(userId);
1849 articleId = articleId.trim().toUpperCase();
1850
1851 Date displayDate = PortalUtil.getDate(
1852 displayDateMonth, displayDateDay, displayDateYear,
1853 displayDateHour, displayDateMinute, user.getTimeZone(),
1854 new ArticleDisplayDateException());
1855
1856 Date expirationDate = null;
1857
1858 if (!neverExpire) {
1859 expirationDate = PortalUtil.getDate(
1860 expirationDateMonth, expirationDateDay, expirationDateYear,
1861 expirationDateHour, expirationDateMinute, user.getTimeZone(),
1862 new ArticleExpirationDateException());
1863 }
1864
1865 Date now = new Date();
1866
1867 boolean expired = false;
1868
1869 if ((expirationDate != null) && expirationDate.before(now)) {
1870 expired = true;
1871 }
1872
1873 Date reviewDate = null;
1874
1875 if (!neverReview) {
1876 reviewDate = PortalUtil.getDate(
1877 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
1878 reviewDateMinute, user.getTimeZone(),
1879 new ArticleReviewDateException());
1880 }
1881
1882 byte[] smallImageBytes = null;
1883
1884 try {
1885 smallImageBytes = FileUtil.getBytes(smallImageFile);
1886 }
1887 catch (IOException ioe) {
1888 }
1889
1890 validate(
1891 user.getCompanyId(), groupId, -1, titleMap, content, type,
1892 structureId, templateId, smallImage, smallImageURL, smallImageFile,
1893 smallImageBytes);
1894
1895 JournalArticle oldArticle = null;
1896 double oldVersion = 0;
1897
1898 boolean incrementVersion = false;
1899
1900 boolean imported = GetterUtil.getBoolean(
1901 serviceContext.getAttribute("imported"));
1902
1903 if (imported) {
1904 oldArticle = getArticle(groupId, articleId, version);
1905 oldVersion = version;
1906
1907 if (!expired) {
1908 incrementVersion = true;
1909 }
1910 else {
1911 return expireArticle(
1912 userId, groupId, articleId, version, articleURL,
1913 serviceContext);
1914 }
1915 }
1916 else {
1917 oldArticle = getLatestArticle(
1918 groupId, articleId, WorkflowConstants.STATUS_ANY);
1919
1920 oldVersion = oldArticle.getVersion();
1921
1922 if ((version > 0) && (version != oldVersion)) {
1923 throw new ArticleVersionException();
1924 }
1925
1926 if (oldArticle.isApproved() || oldArticle.isExpired()) {
1927 incrementVersion = true;
1928 }
1929 }
1930
1931 JournalArticle article = null;
1932
1933 if (incrementVersion) {
1934 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
1935
1936 long id = counterLocalService.increment();
1937
1938 article = journalArticlePersistence.create(id);
1939
1940 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
1941 article.setGroupId(oldArticle.getGroupId());
1942 article.setCompanyId(oldArticle.getCompanyId());
1943 article.setUserId(oldArticle.getUserId());
1944 article.setUserName(oldArticle.getUserName());
1945 article.setCreateDate(serviceContext.getModifiedDate(now));
1946 article.setClassNameId(oldArticle.getClassNameId());
1947 article.setClassPK(oldArticle.getClassPK());
1948 article.setArticleId(articleId);
1949 article.setVersion(newVersion);
1950 article.setSmallImageId(oldArticle.getSmallImageId());
1951 }
1952 else {
1953 article = oldArticle;
1954 }
1955
1956 Locale locale = LocaleUtil.getDefault();
1957
1958 String defaultLanguageId = GetterUtil.getString(
1959 serviceContext.getAttribute("defaultLanguageId"));
1960
1961 if (Validator.isNotNull(defaultLanguageId)) {
1962 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
1963 }
1964
1965 String title = titleMap.get(locale);
1966
1967 content = format(
1968 user, groupId, articleId, article.getVersion(), incrementVersion,
1969 content, structureId, images);
1970
1971 article.setModifiedDate(serviceContext.getModifiedDate(now));
1972 article.setTitleMap(titleMap, locale);
1973 article.setUrlTitle(
1974 getUniqueUrlTitle(article.getId(), groupId, articleId, title));
1975 article.setDescriptionMap(descriptionMap, locale);
1976 article.setContent(content);
1977 article.setType(type);
1978 article.setStructureId(structureId);
1979 article.setTemplateId(templateId);
1980 article.setLayoutUuid(layoutUuid);
1981 article.setDisplayDate(displayDate);
1982 article.setExpirationDate(expirationDate);
1983 article.setReviewDate(reviewDate);
1984 article.setIndexable(indexable);
1985 article.setSmallImage(smallImage);
1986
1987 if (article.getSmallImageId() == 0) {
1988 article.setSmallImageId(counterLocalService.increment());
1989 }
1990
1991 article.setSmallImageURL(smallImageURL);
1992
1993 if (oldArticle.isPending()) {
1994 article.setStatus(oldArticle.getStatus());
1995 }
1996 else if (!expired) {
1997 article.setStatus(WorkflowConstants.STATUS_DRAFT);
1998 }
1999 else {
2000 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
2001 }
2002
2003 journalArticlePersistence.update(article, false);
2004
2005
2006
2007 updateAsset(
2008 userId, article, serviceContext.getAssetCategoryIds(),
2009 serviceContext.getAssetTagNames(),
2010 serviceContext.getAssetLinkEntryIds());
2011
2012
2013
2014 ExpandoBridge expandoBridge = article.getExpandoBridge();
2015
2016 expandoBridge.setAttributes(serviceContext);
2017
2018
2019
2020 saveImages(
2021 smallImage, article.getSmallImageId(), smallImageFile,
2022 smallImageBytes);
2023
2024
2025
2026 PortletPreferences preferences =
2027 ServiceContextUtil.getPortletPreferences(serviceContext);
2028
2029
2030
2031 if (serviceContext.getWorkflowAction() ==
2032 WorkflowConstants.ACTION_PUBLISH) {
2033
2034 sendEmail(article, articleURL, preferences, "requested");
2035
2036 WorkflowHandlerRegistryUtil.startWorkflowInstance(
2037 user.getCompanyId(), groupId, userId,
2038 JournalArticle.class.getName(), article.getId(),
2039 article, serviceContext);
2040 }
2041 else if (article.getVersion() ==
2042 JournalArticleConstants.VERSION_DEFAULT) {
2043
2044
2045
2046 Indexer indexer = IndexerRegistryUtil.getIndexer(
2047 JournalArticle.class);
2048
2049 indexer.reindex(article);
2050 }
2051
2052 return article;
2053 }
2054
2055 public JournalArticle updateArticle(
2056 long userId, long groupId, String articleId, double version,
2057 String content, ServiceContext serviceContext)
2058 throws PortalException, SystemException {
2059
2060 JournalArticle article = journalArticlePersistence.findByG_A_V(
2061 groupId, articleId, version);
2062
2063 return updateArticle(
2064 userId, groupId, articleId, version, article.getTitleMap(),
2065 article.getDescriptionMap(), content, article.getLayoutUuid(),
2066 serviceContext);
2067 }
2068
2069 public JournalArticle updateArticleTranslation(
2070 long groupId, String articleId, double version, Locale locale,
2071 String title, String description, String content)
2072 throws PortalException, SystemException {
2073
2074 validateContent(content);
2075
2076 JournalArticle oldArticle = getLatestArticle(
2077 groupId, articleId, WorkflowConstants.STATUS_ANY);
2078
2079 double oldVersion = oldArticle.getVersion();
2080
2081 if ((version > 0) && (version != oldVersion)) {
2082 throw new ArticleVersionException();
2083 }
2084
2085 JournalArticle article = null;
2086
2087 if (!oldArticle.isDraft()) {
2088 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
2089
2090 long id = counterLocalService.increment();
2091
2092 article = journalArticlePersistence.create(id);
2093
2094 User user = userService.getUserById(oldArticle.getUserId());
2095
2096 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
2097 article.setGroupId(oldArticle.getGroupId());
2098 article.setCompanyId(oldArticle.getCompanyId());
2099 article.setUserId(oldArticle.getUserId());
2100 article.setUserName(user.getFullName());
2101 article.setCreateDate(new Date());
2102 article.setModifiedDate(new Date());
2103 article.setClassNameId(oldArticle.getClassNameId());
2104 article.setClassPK(oldArticle.getClassPK());
2105 article.setArticleId(articleId);
2106 article.setVersion(newVersion);
2107 article.setTitleMap(oldArticle.getTitleMap());
2108 article.setUrlTitle(
2109 getUniqueUrlTitle(article.getId(), groupId, articleId, title));
2110 article.setDescriptionMap(oldArticle.getDescriptionMap());
2111 article.setType(oldArticle.getType());
2112 article.setStructureId(oldArticle.getStructureId());
2113 article.setTemplateId(oldArticle.getTemplateId());
2114 article.setLayoutUuid(oldArticle.getLayoutUuid());
2115 article.setDisplayDate(oldArticle.getDisplayDate());
2116 article.setExpirationDate(oldArticle.getExpirationDate());
2117 article.setReviewDate(oldArticle.getReviewDate());
2118 article.setIndexable(oldArticle.getIndexable());
2119 article.setSmallImage(oldArticle.getSmallImage());
2120 article.setSmallImageId(oldArticle.getSmallImageId());
2121
2122 if (article.getSmallImageId() == 0) {
2123 article.setSmallImageId(counterLocalService.increment());
2124 }
2125
2126 article.setSmallImageURL(oldArticle.getSmallImageURL());
2127
2128 article.setStatus(WorkflowConstants.STATUS_DRAFT);
2129 article.setStatusDate(new Date());
2130 }
2131 else {
2132 article = oldArticle;
2133 }
2134
2135 Map<Locale, String> titleMap = article.getTitleMap();
2136
2137 titleMap.put(locale, title);
2138
2139 article.setTitleMap(titleMap);
2140
2141 Map<Locale, String> descriptionMap = article.getDescriptionMap();
2142
2143 descriptionMap.put(locale, description);
2144
2145 article.setDescriptionMap(descriptionMap);
2146
2147 article.setContent(content);
2148
2149 journalArticlePersistence.update(article, false);
2150
2151 return article;
2152 }
2153
2154 public void updateAsset(
2155 long userId, JournalArticle article, long[] assetCategoryIds,
2156 String[] assetTagNames, long[] assetLinkEntryIds)
2157 throws PortalException, SystemException {
2158
2159
2160
2161
2162 Date[] dateInterval = getDateInterval(
2163 article.getGroupId(), article.getArticleId(),
2164 article.getDisplayDate(), article.getExpirationDate());
2165
2166 Date displayDate = dateInterval[0];
2167 Date expirationDate = dateInterval[1];
2168
2169 boolean visible = article.isApproved();
2170
2171 if (article.getClassNameId() > 0) {
2172 visible = false;
2173 }
2174
2175 boolean addDraftAssetEntry = false;
2176
2177 if (!article.isApproved() &&
2178 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
2179
2180 int approvedArticlesCount =
2181 journalArticlePersistence.countByG_A_ST(
2182 article.getGroupId(), article.getArticleId(),
2183 WorkflowConstants.STATUS_APPROVED);
2184
2185 if (approvedArticlesCount > 0) {
2186 addDraftAssetEntry = true;
2187 }
2188 }
2189
2190 AssetEntry assetEntry = null;
2191
2192 if (addDraftAssetEntry) {
2193 assetEntry = assetEntryLocalService.updateEntry(
2194 userId, article.getGroupId(), JournalArticle.class.getName(),
2195 article.getPrimaryKey(), article.getUuid(),
2196 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
2197 null, null, displayDate, expirationDate, ContentTypes.TEXT_HTML,
2198 article.getTitle(), article.getDescription(),
2199 article.getDescription(), null, article.getLayoutUuid(), 0, 0,
2200 null, false);
2201 }
2202 else {
2203 JournalArticleResource journalArticleResource =
2204 journalArticleResourceLocalService.getArticleResource(
2205 article.getResourcePrimKey());
2206
2207 assetEntry = assetEntryLocalService.updateEntry(
2208 userId, article.getGroupId(), JournalArticle.class.getName(),
2209 journalArticleResource.getResourcePrimKey(),
2210 journalArticleResource.getUuid(), getClassTypeId(article),
2211 assetCategoryIds, assetTagNames, visible, null, null,
2212 displayDate, expirationDate, ContentTypes.TEXT_HTML,
2213 article.getTitle(), article.getDescription(),
2214 article.getDescription(), null, article.getLayoutUuid(), 0, 0,
2215 null, false);
2216 }
2217
2218 assetLinkLocalService.updateLinks(
2219 userId, assetEntry.getEntryId(), assetLinkEntryIds,
2220 AssetLinkConstants.TYPE_RELATED);
2221 }
2222
2223 public JournalArticle updateContent(
2224 long groupId, String articleId, double version, String content)
2225 throws PortalException, SystemException {
2226
2227 JournalArticle article = journalArticlePersistence.findByG_A_V(
2228 groupId, articleId, version);
2229
2230 article.setContent(content);
2231
2232 journalArticlePersistence.update(article, false);
2233
2234 return article;
2235 }
2236
2237 public JournalArticle updateStatus(
2238 long userId, JournalArticle article, int status, String articleURL,
2239 ServiceContext serviceContext)
2240 throws PortalException, SystemException {
2241
2242
2243
2244 User user = userPersistence.findByPrimaryKey(userId);
2245 Date now = new Date();
2246
2247 int oldStatus = article.getStatus();
2248
2249 article.setModifiedDate(serviceContext.getModifiedDate(now));
2250
2251 boolean neverExpire = false;
2252
2253 if (status == WorkflowConstants.STATUS_APPROVED) {
2254 Date expirationDate = article.getExpirationDate();
2255
2256 if ((expirationDate != null) && expirationDate.before(now)) {
2257 neverExpire = true;
2258
2259 article.setExpirationDate(null);
2260 }
2261 }
2262
2263 if (status == WorkflowConstants.STATUS_EXPIRED) {
2264 article.setExpirationDate(now);
2265 }
2266
2267 article.setStatus(status);
2268 article.setStatusByUserId(user.getUserId());
2269 article.setStatusByUserName(user.getFullName());
2270 article.setStatusDate(serviceContext.getModifiedDate(now));
2271
2272 journalArticlePersistence.update(article, false);
2273
2274 if (isLatestVersion(
2275 article.getGroupId(), article.getArticleId(),
2276 article.getVersion())) {
2277
2278 if (status == WorkflowConstants.STATUS_APPROVED) {
2279 updateUrlTitles(
2280 article.getGroupId(), article.getArticleId(),
2281 article.getUrlTitle());
2282
2283
2284
2285 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
2286 (article.getVersion() !=
2287 JournalArticleConstants.VERSION_DEFAULT)) {
2288
2289 AssetEntry draftAssetEntry = null;
2290
2291 try {
2292 draftAssetEntry = assetEntryLocalService.getEntry(
2293 JournalArticle.class.getName(),
2294 article.getPrimaryKey());
2295
2296 Date[] dateInterval = getDateInterval(
2297 article.getGroupId(), article.getArticleId(),
2298 article.getDisplayDate(),
2299 article.getExpirationDate());
2300
2301 Date displayDate = dateInterval[0];
2302 Date expirationDate = dateInterval[1];
2303
2304 long[] assetCategoryIds =
2305 draftAssetEntry.getCategoryIds();
2306 String[] assetTagNames = draftAssetEntry.getTagNames();
2307
2308 List<AssetLink> assetLinks =
2309 assetLinkLocalService.getDirectLinks(
2310 draftAssetEntry.getEntryId(),
2311 AssetLinkConstants.TYPE_RELATED);
2312
2313 long[] assetLinkEntryIds = StringUtil.split(
2314 ListUtil.toString(
2315 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
2316
2317 boolean visible = true;
2318
2319 if (article.getClassNameId() > 0) {
2320 visible = false;
2321 }
2322
2323 AssetEntry assetEntry =
2324 assetEntryLocalService.updateEntry(
2325 userId, article.getGroupId(),
2326 JournalArticle.class.getName(),
2327 article.getResourcePrimKey(), article.getUuid(),
2328 getClassTypeId(article), assetCategoryIds,
2329 assetTagNames, visible, null, null, displayDate,
2330 expirationDate, ContentTypes.TEXT_HTML,
2331 article.getTitle(), article.getDescription(),
2332 article.getDescription(), null,
2333 article.getLayoutUuid(), 0, 0, null, false);
2334
2335 assetLinkLocalService.updateLinks(
2336 userId, assetEntry.getEntryId(),
2337 assetLinkEntryIds, AssetLinkConstants.TYPE_RELATED);
2338
2339 assetEntryLocalService.deleteEntry(
2340 JournalArticle.class.getName(),
2341 article.getPrimaryKey());
2342 }
2343 catch (NoSuchEntryException nsee) {
2344 }
2345 }
2346
2347 if (article.getClassNameId() == 0) {
2348 AssetEntry assetEntry =
2349 assetEntryLocalService.updateVisible(
2350 JournalArticle.class.getName(),
2351 article.getResourcePrimKey(), true);
2352
2353 if (neverExpire) {
2354 assetEntry.setExpirationDate(null);
2355
2356 assetEntryLocalService.updateAssetEntry(
2357 assetEntry, false);
2358 }
2359 }
2360
2361
2362
2363 ExpandoBridge expandoBridge = article.getExpandoBridge();
2364
2365 expandoBridge.setAttributes(serviceContext);
2366
2367
2368
2369 Indexer indexer = IndexerRegistryUtil.getIndexer(
2370 JournalArticle.class);
2371
2372 indexer.reindex(article);
2373 }
2374 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
2375 updatePreviousApprovedArticle(article);
2376 }
2377 }
2378
2379 if (article.getClassNameId() == 0) {
2380
2381
2382
2383 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
2384 ((status == WorkflowConstants.STATUS_APPROVED) ||
2385 (status == WorkflowConstants.STATUS_DENIED))) {
2386
2387 String msg = "granted";
2388
2389 if (status == WorkflowConstants.STATUS_DENIED) {
2390 msg = "denied";
2391 }
2392
2393 try {
2394 PortletPreferences preferences =
2395 ServiceContextUtil.getPortletPreferences(
2396 serviceContext);
2397
2398 sendEmail(article, articleURL, preferences, msg);
2399 }
2400 catch (Exception e) {
2401 _log.error(
2402 "Unable to send email to notify the change of status " +
2403 " to " + msg + " for article " + article.getId() +
2404 ": " + e.getMessage());
2405 }
2406 }
2407
2408
2409
2410 notifySubscribers(article, serviceContext);
2411 }
2412
2413 return article;
2414 }
2415
2416 public JournalArticle updateStatus(
2417 long userId, long classPK, int status,
2418 ServiceContext serviceContext)
2419 throws PortalException, SystemException {
2420
2421 JournalArticle article = getArticle(classPK);
2422
2423 return updateStatus(userId, article, status, null, serviceContext);
2424 }
2425
2426 public JournalArticle updateStatus(
2427 long userId, long groupId, String articleId, double version,
2428 int status, String articleURL, ServiceContext serviceContext)
2429 throws PortalException, SystemException {
2430
2431 JournalArticle article = journalArticlePersistence.findByG_A_V(
2432 groupId, articleId, version);
2433
2434 return updateStatus(
2435 userId, article, status, articleURL, serviceContext);
2436 }
2437
2438 public void updateTemplateId(
2439 long groupId, long classNameId, String oldTemplateId,
2440 String newTemplateId)
2441 throws SystemException {
2442
2443 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
2444 groupId, classNameId, oldTemplateId);
2445
2446 for (JournalArticle article : articles) {
2447 article.setTemplateId(newTemplateId);
2448
2449 journalArticlePersistence.update(article, false);
2450 }
2451 }
2452
2453 protected void checkStructure(Document contentDoc, Element root)
2454 throws PortalException {
2455
2456 for (Element el : root.elements()) {
2457 checkStructureField(el, contentDoc);
2458
2459 checkStructure(contentDoc, el);
2460 }
2461 }
2462
2463 protected void checkStructure(JournalArticle article)
2464 throws DocumentException, PortalException, SystemException {
2465
2466 Group companyGroup = groupLocalService.getCompanyGroup(
2467 article.getCompanyId());
2468
2469 JournalStructure structure = null;
2470
2471 try {
2472 structure = journalStructurePersistence.findByG_S(
2473 article.getGroupId(), article.getStructureId());
2474 }
2475 catch (NoSuchStructureException nsse) {
2476 structure = journalStructurePersistence.findByG_S(
2477 companyGroup.getGroupId(), article.getStructureId());
2478 }
2479
2480 String content = GetterUtil.getString(article.getContent());
2481
2482 Document contentDoc = SAXReaderUtil.read(content);
2483 Document xsdDoc = SAXReaderUtil.read(structure.getXsd());
2484
2485 try {
2486 checkStructure(contentDoc, xsdDoc.getRootElement());
2487 }
2488 catch (StructureXsdException sxsde) {
2489 long groupId = article.getGroupId();
2490 String articleId = article.getArticleId();
2491 double version = article.getVersion();
2492
2493 if (_log.isWarnEnabled()) {
2494 _log.warn(
2495 "Article {groupId=" + groupId + ", articleId=" +
2496 articleId + ", version=" + version +
2497 "} has content that does not match its " +
2498 "structure: " + sxsde.getMessage());
2499 }
2500 }
2501 }
2502
2503 protected void checkStructureField(Element el, Document contentDoc)
2504 throws PortalException {
2505
2506 StringBuilder elPath = new StringBuilder();
2507
2508 elPath.append(el.attributeValue("name"));
2509
2510 Element elParent = el.getParent();
2511
2512 for (;;) {
2513 if ((elParent == null) ||
2514 (elParent.getName().equals("root"))) {
2515
2516 break;
2517 }
2518
2519 elPath.insert(
2520 0, elParent.attributeValue("name") + StringPool.COMMA);
2521
2522 elParent = elParent.getParent();
2523 }
2524
2525 String[] elPathNames = StringUtil.split(elPath.toString());
2526
2527 Element contentEl = contentDoc.getRootElement();
2528
2529 for (String _elPathName : elPathNames) {
2530 boolean foundEl = false;
2531
2532 for (Element tempEl : contentEl.elements()) {
2533 if (_elPathName.equals(
2534 tempEl.attributeValue("name", StringPool.BLANK))) {
2535
2536 contentEl = tempEl;
2537 foundEl = true;
2538
2539 break;
2540 }
2541 }
2542
2543 if (!foundEl) {
2544 String elType = contentEl.attributeValue(
2545 "type", StringPool.BLANK);
2546
2547 if (!elType.equals("list") && !elType.equals("multi-list")) {
2548 throw new StructureXsdException(elPath.toString());
2549 }
2550
2551 break;
2552 }
2553 }
2554 }
2555
2556 protected void copyArticleImages(
2557 JournalArticle oldArticle, JournalArticle newArticle)
2558 throws Exception {
2559
2560 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
2561
2562 XPath xpathSelector = SAXReaderUtil.createXPath(
2563 "
2564
2565 List<Node> imageNodes = xpathSelector.selectNodes(contentDoc);
2566
2567 for (Node imageNode : imageNodes) {
2568 Element imageEl = (Element)imageNode;
2569
2570 String instanceId = imageEl.attributeValue("instance-id");
2571 String name = imageEl.attributeValue("name");
2572
2573 List<Element> dynamicContentEls = imageEl.elements(
2574 "dynamic-content");
2575
2576 for (Element dynamicContentEl : dynamicContentEls) {
2577 long imageId = GetterUtil.getLong(
2578 dynamicContentEl.attributeValue("id"));
2579 String languageId = dynamicContentEl.attributeValue(
2580 "language-id");
2581
2582 Image oldImage = null;
2583
2584 try {
2585 oldImage = imageLocalService.getImage(imageId);
2586 }
2587 catch (NoSuchImageException nsie) {
2588 continue;
2589 }
2590
2591 imageId = journalArticleImageLocalService.getArticleImageId(
2592 newArticle.getGroupId(), newArticle.getArticleId(),
2593 newArticle.getVersion(), instanceId, name, languageId);
2594
2595 imageLocalService.updateImage(imageId, oldImage.getTextObj());
2596
2597 String elContent =
2598 "/image/journal/article?img_id=" + imageId + "&t=" +
2599 WebServerServletTokenUtil.getToken(imageId);
2600
2601 dynamicContentEl.setText(elContent);
2602 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
2603 }
2604 }
2605
2606 newArticle.setContent(contentDoc.formattedString());
2607 }
2608
2609 protected void format(
2610 User user, long groupId, String articleId, double version,
2611 boolean incrementVersion, Element root, Map<String, byte[]> images)
2612 throws PortalException, SystemException {
2613
2614 for (Element element : root.elements()) {
2615 String elInstanceId = element.attributeValue(
2616 "instance-id", StringPool.BLANK);
2617 String elName = element.attributeValue("name", StringPool.BLANK);
2618 String elType = element.attributeValue("type", StringPool.BLANK);
2619
2620 if (elType.equals("image")) {
2621 formatImage(
2622 groupId, articleId, version, incrementVersion, element,
2623 elInstanceId, elName, images);
2624 }
2625 else if (elType.equals("text_area") || elType.equals("text") ||
2626 elType.equals("text_box")) {
2627
2628 List<Element> dynamicContentElements = element.elements(
2629 "dynamic-content");
2630
2631 for (Element dynamicContentElement : dynamicContentElements) {
2632 String dynamicContent = dynamicContentElement.getText();
2633
2634 if (Validator.isNotNull(dynamicContent)) {
2635 dynamicContent = SanitizerUtil.sanitize(
2636 user.getCompanyId(), groupId, user.getUserId(),
2637 JournalArticle.class.getName(), 0,
2638 ContentTypes.TEXT_HTML, dynamicContent);
2639
2640 dynamicContentElement.setText(dynamicContent);
2641 }
2642 }
2643 }
2644
2645 format(
2646 user, groupId, articleId, version, incrementVersion, element,
2647 images);
2648 }
2649 }
2650
2651 protected String format(
2652 User user, long groupId, String articleId, double version,
2653 boolean incrementVersion, String content, String structureId,
2654 Map<String, byte[]> images)
2655 throws PortalException, SystemException {
2656
2657 Document document = null;
2658
2659 try {
2660 document = SAXReaderUtil.read(content);
2661
2662 Element rootElement = document.getRootElement();
2663
2664 if (Validator.isNotNull(structureId)) {
2665 format(
2666 user, groupId, articleId, version, incrementVersion,
2667 rootElement, images);
2668 }
2669 else {
2670 List<Element> staticContentElements = rootElement.elements(
2671 "static-content");
2672
2673 for (Element staticContentElement : staticContentElements) {
2674 String staticContent = staticContentElement.getText();
2675
2676 staticContent = SanitizerUtil.sanitize(
2677 user.getCompanyId(), groupId, user.getUserId(),
2678 JournalArticle.class.getName(), 0,
2679 ContentTypes.TEXT_HTML, staticContent);
2680
2681 staticContentElement.setText(staticContent);
2682 }
2683 }
2684
2685 content = DDMXMLUtil.formatXML(document);
2686 }
2687 catch (DocumentException de) {
2688 _log.error(de);
2689 }
2690 catch (IOException ioe) {
2691 _log.error(ioe);
2692 }
2693
2694 content = HtmlUtil.replaceMsWordCharacters(content);
2695
2696 return content;
2697 }
2698
2699 protected void formatImage(
2700 long groupId, String articleId, double version,
2701 boolean incrementVersion, Element el, String elInstanceId,
2702 String elName, Map<String, byte[]> images)
2703 throws PortalException, SystemException {
2704
2705 List<Element> imageContents = el.elements("dynamic-content");
2706
2707 for (Element dynamicContent : imageContents) {
2708 String elLanguage = dynamicContent.attributeValue(
2709 "language-id", StringPool.BLANK);
2710
2711 if (!elLanguage.equals(StringPool.BLANK)) {
2712 elLanguage = "_" + elLanguage;
2713 }
2714
2715 long imageId =
2716 journalArticleImageLocalService.getArticleImageId(
2717 groupId, articleId, version, elInstanceId, elName,
2718 elLanguage);
2719
2720 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
2721
2722 long oldImageId = 0;
2723
2724 if ((oldVersion >= 1) && incrementVersion) {
2725 oldImageId =
2726 journalArticleImageLocalService.getArticleImageId(
2727 groupId, articleId, oldVersion, elInstanceId, elName,
2728 elLanguage);
2729 }
2730
2731 String elContent =
2732 "/image/journal/article?img_id=" + imageId + "&t=" +
2733 WebServerServletTokenUtil.getToken(imageId);
2734
2735 if (dynamicContent.getText().equals("delete")) {
2736 dynamicContent.setText(StringPool.BLANK);
2737
2738 imageLocalService.deleteImage(imageId);
2739
2740 String defaultElLanguage = "";
2741
2742 if (!Validator.isNotNull(elLanguage)) {
2743 defaultElLanguage =
2744 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2745 }
2746
2747 long defaultImageId =
2748 journalArticleImageLocalService.getArticleImageId(
2749 groupId, articleId, version, elInstanceId, elName,
2750 defaultElLanguage);
2751
2752 imageLocalService.deleteImage(defaultImageId);
2753
2754 continue;
2755 }
2756
2757 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
2758
2759 if (bytes != null && (bytes.length > 0)) {
2760 dynamicContent.setText(elContent);
2761 dynamicContent.addAttribute("id", String.valueOf(imageId));
2762
2763 imageLocalService.updateImage(imageId, bytes);
2764
2765 continue;
2766 }
2767
2768 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
2769 (incrementVersion)) {
2770
2771 Image oldImage = null;
2772
2773 if (oldImageId > 0) {
2774 oldImage = imageLocalService.getImage(oldImageId);
2775 }
2776
2777 if (oldImage != null) {
2778 dynamicContent.setText(elContent);
2779 dynamicContent.addAttribute("id", String.valueOf(imageId));
2780
2781 bytes = oldImage.getTextObj();
2782
2783 imageLocalService.updateImage(imageId, bytes);
2784 }
2785
2786 continue;
2787 }
2788
2789 Image image = imageLocalService.getImage(imageId);
2790
2791 if (image != null) {
2792 dynamicContent.setText(elContent);
2793 dynamicContent.addAttribute("id", String.valueOf(imageId));
2794
2795 continue;
2796 }
2797
2798 long contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2799 dynamicContent.getText(), "img_id"));
2800
2801 if (contentImageId <= 0) {
2802 contentImageId = GetterUtil.getLong(HttpUtil.getParameter(
2803 dynamicContent.getText(), "img_id", false));
2804 }
2805
2806 if (contentImageId > 0) {
2807 image = imageLocalService.getImage(contentImageId);
2808
2809 if (image != null) {
2810 dynamicContent.addAttribute(
2811 "id", String.valueOf(contentImageId));
2812
2813 continue;
2814 }
2815 }
2816
2817 String defaultElLanguage = "";
2818
2819 if (!Validator.isNotNull(elLanguage)) {
2820 defaultElLanguage =
2821 "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
2822 }
2823
2824 long defaultImageId =
2825 journalArticleImageLocalService.getArticleImageId(
2826 groupId, articleId, version, elInstanceId, elName,
2827 defaultElLanguage);
2828
2829 Image defaultImage = imageLocalService.getImage(defaultImageId);
2830
2831 if (defaultImage != null) {
2832 dynamicContent.setText(elContent);
2833 dynamicContent.addAttribute(
2834 "id", String.valueOf(defaultImageId));
2835
2836 bytes = defaultImage.getTextObj();
2837
2838 imageLocalService.updateImage(defaultImageId, bytes);
2839
2840 continue;
2841 }
2842
2843 dynamicContent.setText(StringPool.BLANK);
2844 }
2845 }
2846
2847 protected long getClassTypeId(JournalArticle article) {
2848 long classTypeId = 0;
2849
2850 try {
2851 JournalStructure structure = journalStructurePersistence.fetchByG_S(
2852 article.getGroupId(), article.getStructureId());
2853
2854 if (structure == null) {
2855 Group companyGroup = groupLocalService.getCompanyGroup(
2856 article.getCompanyId());
2857
2858 structure = journalStructurePersistence.fetchByG_S(
2859 companyGroup.getGroupId(), article.getStructureId());
2860 }
2861
2862 if (structure != null) {
2863 classTypeId = structure.getId();
2864 }
2865 }
2866 catch (Exception e) {
2867 _log.error(e, e);
2868 }
2869
2870 return classTypeId;
2871 }
2872
2873 protected Date[] getDateInterval(
2874 long groupId, String articleId, Date earliestDisplayDate,
2875 Date latestExpirationDate)
2876 throws SystemException {
2877
2878 Date[] dateInterval = new Date[2];
2879
2880 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2881 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2882
2883 boolean expiringArticle = true;
2884
2885 if (latestExpirationDate == null) {
2886 expiringArticle = false;
2887 }
2888
2889 for (JournalArticle article : articles) {
2890 if ((earliestDisplayDate == null) ||
2891 ((article.getDisplayDate() != null) &&
2892 earliestDisplayDate.after(article.getDisplayDate()))) {
2893
2894 earliestDisplayDate = article.getDisplayDate();
2895 }
2896
2897 if (expiringArticle &&
2898 ((latestExpirationDate == null) ||
2899 ((article.getExpirationDate() != null) &&
2900 latestExpirationDate.before(article.getExpirationDate())))) {
2901
2902 latestExpirationDate = article.getExpirationDate();
2903 }
2904
2905 if (expiringArticle && (article.getExpirationDate() == null) &&
2906 (latestExpirationDate != null)) {
2907
2908 expiringArticle = false;
2909 }
2910 }
2911
2912 dateInterval[0] = earliestDisplayDate;
2913 dateInterval[1] = latestExpirationDate;
2914
2915 return dateInterval;
2916 }
2917
2918 protected String getUniqueUrlTitle(
2919 long id, long groupId, String articleId, String title)
2920 throws PortalException, SystemException {
2921
2922 String urlTitle = JournalUtil.getUrlTitle(id, title);
2923
2924 String newUrlTitle = ModelHintsUtil.trimString(
2925 JournalArticle.class.getName(), "urlTitle", urlTitle);
2926
2927 for (int i = 1;; i++) {
2928 JournalArticle article = null;
2929
2930 try {
2931 article = getArticleByUrlTitle(groupId, newUrlTitle);
2932 }
2933 catch (NoSuchArticleException nsae) {
2934 }
2935
2936 if ((article == null) || article.getArticleId().equals(articleId)) {
2937 break;
2938 }
2939 else {
2940 String suffix = StringPool.DASH + i;
2941
2942 String prefix = newUrlTitle;
2943
2944 if (newUrlTitle.length() > suffix.length()) {
2945 prefix = newUrlTitle.substring(
2946 0, newUrlTitle.length() - suffix.length());
2947 }
2948
2949 newUrlTitle = prefix + suffix;
2950 }
2951 }
2952
2953 return newUrlTitle;
2954 }
2955
2956 protected void notifySubscribers(
2957 JournalArticle article, ServiceContext serviceContext)
2958 throws PortalException, SystemException {
2959
2960 if (!article.isApproved()) {
2961 return;
2962 }
2963
2964 String articleURL = PortalUtil.getControlPanelFullURL(
2965 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
2966
2967 if (Validator.isNull(articleURL)) {
2968 return;
2969 }
2970
2971 PortletPreferences preferences =
2972 ServiceContextUtil.getPortletPreferences(serviceContext);
2973
2974 if (preferences == null) {
2975 long ownerId = article.getGroupId();
2976 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
2977 long plid = PortletKeys.PREFS_PLID_SHARED;
2978 String portletId = PortletKeys.JOURNAL;
2979 String defaultPreferences = null;
2980
2981 preferences = portletPreferencesLocalService.getPreferences(
2982 article.getCompanyId(), ownerId, ownerType, plid, portletId,
2983 defaultPreferences);
2984 }
2985
2986 if ((article.getVersion() == 1.0) &&
2987 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
2988 }
2989 else if ((article.getVersion() != 1.0) &&
2990 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
2991 }
2992 else {
2993 return;
2994 }
2995
2996 String fromName = JournalUtil.getEmailFromName(
2997 preferences, article.getCompanyId());
2998 String fromAddress = JournalUtil.getEmailFromAddress(
2999 preferences, article.getCompanyId());
3000
3001 String subject = null;
3002 String body = null;
3003
3004 if (article.getVersion() == 1.0) {
3005 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
3006 body = JournalUtil.getEmailArticleAddedBody(preferences);
3007 }
3008 else {
3009 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
3010 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
3011 }
3012
3013 SubscriptionSender subscriptionSender = new SubscriptionSender();
3014
3015 subscriptionSender.setBody(body);
3016 subscriptionSender.setCompanyId(article.getCompanyId());
3017 subscriptionSender.setContextAttributes(
3018 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
3019 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
3020 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
3021 subscriptionSender.setContextUserPrefix("ARTICLE");
3022 subscriptionSender.setFrom(fromAddress, fromName);
3023 subscriptionSender.setHtmlFormat(true);
3024 subscriptionSender.setMailId("journal_article", article.getId());
3025 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
3026 subscriptionSender.setReplyToAddress(fromAddress);
3027 subscriptionSender.setScopeGroupId(article.getGroupId());
3028 subscriptionSender.setSubject(subject);
3029 subscriptionSender.setUserId(article.getUserId());
3030
3031 subscriptionSender.addPersistedSubscribers(
3032 JournalArticle.class.getName(), article.getGroupId());
3033
3034 subscriptionSender.flushNotificationsAsync();
3035 }
3036
3037 protected void saveImages(
3038 boolean smallImage, long smallImageId, File smallImageFile,
3039 byte[] smallImageBytes)
3040 throws PortalException, SystemException {
3041
3042 if (smallImage) {
3043 if ((smallImageFile != null) && (smallImageBytes != null)) {
3044 imageLocalService.updateImage(smallImageId, smallImageBytes);
3045 }
3046 }
3047 else {
3048 imageLocalService.deleteImage(smallImageId);
3049 }
3050 }
3051
3052 protected void sendEmail(
3053 JournalArticle article, String articleURL,
3054 PortletPreferences preferences, String emailType)
3055 throws PortalException, SystemException {
3056
3057 if (preferences == null) {
3058 return;
3059 }
3060 else if (emailType.equals("denied") &&
3061 JournalUtil.getEmailArticleApprovalDeniedEnabled(preferences)) {
3062 }
3063 else if (emailType.equals("granted") &&
3064 JournalUtil.getEmailArticleApprovalGrantedEnabled(
3065 preferences)) {
3066 }
3067 else if (emailType.equals("requested") &&
3068 JournalUtil.getEmailArticleApprovalRequestedEnabled(
3069 preferences)) {
3070 }
3071 else if (emailType.equals("review") &&
3072 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
3073 }
3074 else {
3075 return;
3076 }
3077
3078 Company company = companyPersistence.findByPrimaryKey(
3079 article.getCompanyId());
3080
3081 User user = userPersistence.findByPrimaryKey(article.getUserId());
3082
3083 articleURL +=
3084 "&groupId=" + article.getGroupId() + "&articleId=" +
3085 article.getArticleId() + "&version=" + article.getVersion();
3086
3087 String fromName = JournalUtil.getEmailFromName(
3088 preferences, article.getCompanyId());
3089 String fromAddress = JournalUtil.getEmailFromAddress(
3090 preferences, article.getCompanyId());
3091
3092 String toName = user.getFullName();
3093 String toAddress = user.getEmailAddress();
3094
3095 if (emailType.equals("requested") ||
3096 emailType.equals("review")) {
3097
3098 String tempToName = fromName;
3099 String tempToAddress = fromAddress;
3100
3101 fromName = toName;
3102 fromAddress = toAddress;
3103
3104 toName = tempToName;
3105 toAddress = tempToAddress;
3106 }
3107
3108 String subject = null;
3109 String body = null;
3110
3111 if (emailType.equals("denied")) {
3112 subject =
3113 JournalUtil.getEmailArticleApprovalDeniedSubject(preferences);
3114 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
3115 }
3116 else if (emailType.equals("granted")) {
3117 subject =
3118 JournalUtil.getEmailArticleApprovalGrantedSubject(preferences);
3119 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
3120 }
3121 else if (emailType.equals("requested")) {
3122 subject =
3123 JournalUtil.getEmailArticleApprovalRequestedSubject(
3124 preferences);
3125 body = JournalUtil.getEmailArticleApprovalRequestedBody(
3126 preferences);
3127 }
3128 else if (emailType.equals("review")) {
3129 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
3130 body = JournalUtil.getEmailArticleReviewBody(preferences);
3131 }
3132
3133 SubscriptionSender subscriptionSender = new SubscriptionSender();
3134
3135 subscriptionSender.setBody(body);
3136 subscriptionSender.setCompanyId(company.getCompanyId());
3137 subscriptionSender.setContextAttributes(
3138 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
3139 article.getTitle(), "[$ARTICLE_URL$]", articleURL,
3140 "[$ARTICLE_USER_NAME$]", article.getUserName(),
3141 "[$ARTICLE_VERSION$]", article.getVersion());
3142 subscriptionSender.setContextUserPrefix("ARTICLE");
3143 subscriptionSender.setFrom(fromAddress, fromName);
3144 subscriptionSender.setHtmlFormat(true);
3145 subscriptionSender.setMailId("journal_article", article.getId());
3146 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
3147 subscriptionSender.setScopeGroupId(article.getGroupId());
3148 subscriptionSender.setSubject(subject);
3149 subscriptionSender.setUserId(article.getUserId());
3150
3151 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
3152
3153 subscriptionSender.flushNotificationsAsync();
3154 }
3155
3156 protected void updatePreviousApprovedArticle(JournalArticle article)
3157 throws PortalException, SystemException {
3158
3159 List<JournalArticle> approvedArticles =
3160 journalArticlePersistence.findByG_A_ST(
3161 article.getGroupId(), article.getArticleId(),
3162 WorkflowConstants.STATUS_APPROVED, 0, 2);
3163
3164 if (approvedArticles.isEmpty() ||
3165 ((approvedArticles.size() == 1) &&
3166 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
3167
3168 if (article.isIndexable()) {
3169 Indexer indexer = IndexerRegistryUtil.getIndexer(
3170 JournalArticle.class);
3171
3172 indexer.delete(article);
3173 }
3174
3175 assetEntryLocalService.updateVisible(
3176 JournalArticle.class.getName(), article.getResourcePrimKey(),
3177 false);
3178 }
3179 else {
3180 JournalArticle previousApprovedArticle = approvedArticles.get(0);
3181
3182 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
3183 previousApprovedArticle = approvedArticles.get(1);
3184 }
3185
3186 if (article.isIndexable()) {
3187 Indexer indexer = IndexerRegistryUtil.getIndexer(
3188 JournalArticle.class);
3189
3190 indexer.reindex(previousApprovedArticle);
3191 }
3192 }
3193 }
3194
3195 protected void updateUrlTitles(
3196 long groupId, String articleId, String urlTitle)
3197 throws SystemException {
3198
3199 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3200 groupId, articleId);
3201
3202 for (JournalArticle article : articles) {
3203 if (!article.getUrlTitle().equals(urlTitle)) {
3204 article.setUrlTitle(urlTitle);
3205
3206 journalArticlePersistence.update(article, false);
3207 }
3208 }
3209 }
3210
3211 protected void validate(
3212 long companyId, long groupId, long classNameId,
3213 Map<Locale, String> titleMap, String content, String type,
3214 String structureId, String templateId, boolean smallImage,
3215 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
3216 throws PortalException, SystemException {
3217
3218 Locale defaultLocale = LocaleUtil.fromLanguageId(
3219 LocalizationUtil.getDefaultLocale(content));
3220
3221 if ((classNameId == 0) &&
3222 (titleMap.isEmpty() ||
3223 Validator.isNull(titleMap.get(defaultLocale)))) {
3224
3225 throw new ArticleTitleException();
3226 }
3227 else if (Validator.isNull(type)) {
3228 throw new ArticleTypeException();
3229 }
3230
3231 validateContent(content);
3232
3233 if (Validator.isNotNull(structureId)) {
3234 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
3235
3236 try {
3237 journalStructurePersistence.findByG_S(
3238 groupId, structureId);
3239 }
3240 catch (NoSuchStructureException nsse) {
3241 journalStructurePersistence.findByG_S(
3242 companyGroup.getGroupId(), structureId);
3243 }
3244
3245 JournalTemplate template = null;
3246
3247 if (Validator.isNotNull(templateId)) {
3248 try {
3249 template = journalTemplatePersistence.findByG_T(
3250 groupId, templateId);
3251 }
3252 catch (NoSuchTemplateException nste) {
3253 template = journalTemplatePersistence.findByG_T(
3254 companyGroup.getGroupId(), templateId);
3255 }
3256
3257 if (!template.getStructureId().equals(structureId)) {
3258 throw new NoSuchTemplateException();
3259 }
3260 }
3261 else if (classNameId == 0) {
3262 throw new NoSuchTemplateException();
3263 }
3264 }
3265
3266 String[] imageExtensions = PrefsPropsUtil.getStringArray(
3267 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
3268
3269 if (smallImage && Validator.isNull(smallImageURL) &&
3270 (smallImageFile != null) && (smallImageBytes != null)) {
3271
3272 String smallImageName = smallImageFile.getName();
3273
3274 if (smallImageName != null) {
3275 boolean validSmallImageExtension = false;
3276
3277 for (String _imageExtension : imageExtensions) {
3278 if (StringPool.STAR.equals(_imageExtension) ||
3279 StringUtil.endsWith(smallImageName, _imageExtension)) {
3280
3281 validSmallImageExtension = true;
3282
3283 break;
3284 }
3285 }
3286
3287 if (!validSmallImageExtension) {
3288 throw new ArticleSmallImageNameException(smallImageName);
3289 }
3290 }
3291
3292 long smallImageMaxSize = PrefsPropsUtil.getLong(
3293 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
3294
3295 if ((smallImageMaxSize > 0) &&
3296 ((smallImageBytes == null) ||
3297 (smallImageBytes.length > smallImageMaxSize))) {
3298
3299 throw new ArticleSmallImageSizeException();
3300 }
3301 }
3302 }
3303
3304 protected void validate(
3305 long companyId, long groupId, long classNameId, String articleId,
3306 boolean autoArticleId, double version, Map<Locale, String> titleMap,
3307 String content, String type, String structureId, String templateId,
3308 boolean smallImage, String smallImageURL, File smallImageFile,
3309 byte[] smallImageBytes)
3310 throws PortalException, SystemException {
3311
3312 if (!autoArticleId) {
3313 validate(groupId, articleId);
3314 }
3315
3316 validate(
3317 companyId, groupId, classNameId, titleMap, content, type,
3318 structureId,templateId, smallImage, smallImageURL, smallImageFile,
3319 smallImageBytes);
3320 }
3321
3322 protected void validate(long groupId, String articleId)
3323 throws PortalException, SystemException {
3324
3325 if ((Validator.isNull(articleId)) ||
3326 (articleId.indexOf(CharPool.SPACE) != -1)) {
3327
3328 throw new ArticleIdException();
3329 }
3330
3331 if (journalArticlePersistence.countByG_A(groupId, articleId) > 0) {
3332 throw new DuplicateArticleIdException();
3333 }
3334 }
3335
3336 protected void validateContent(String content) throws PortalException {
3337 if (Validator.isNull(content)) {
3338 throw new ArticleContentException();
3339 }
3340
3341 try {
3342 SAXReaderUtil.read(content);
3343 }
3344 catch (DocumentException de) {
3345 throw new ArticleContentException();
3346 }
3347 }
3348
3349 private static long _JOURNAL_ARTICLE_CHECK_INTERVAL =
3350 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
3351
3352 private static Log _log = LogFactoryUtil.getLog(
3353 JournalArticleLocalServiceImpl.class);
3354
3355 }