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