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