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