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