001
014
015 package com.liferay.portlet.journal.util;
016
017 import com.liferay.portal.kernel.configuration.Filter;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
023 import com.liferay.portal.kernel.portlet.LiferayWindowState;
024 import com.liferay.portal.kernel.search.Field;
025 import com.liferay.portal.kernel.search.Hits;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.templateparser.TransformerListener;
029 import com.liferay.portal.kernel.util.ArrayUtil;
030 import com.liferay.portal.kernel.util.CharPool;
031 import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
032 import com.liferay.portal.kernel.util.GetterUtil;
033 import com.liferay.portal.kernel.util.HtmlUtil;
034 import com.liferay.portal.kernel.util.HttpUtil;
035 import com.liferay.portal.kernel.util.InstanceFactory;
036 import com.liferay.portal.kernel.util.LocaleUtil;
037 import com.liferay.portal.kernel.util.OrderByComparator;
038 import com.liferay.portal.kernel.util.ParamUtil;
039 import com.liferay.portal.kernel.util.PropsKeys;
040 import com.liferay.portal.kernel.util.StringBundler;
041 import com.liferay.portal.kernel.util.StringPool;
042 import com.liferay.portal.kernel.util.StringUtil;
043 import com.liferay.portal.kernel.util.Time;
044 import com.liferay.portal.kernel.util.Tuple;
045 import com.liferay.portal.kernel.util.UnmodifiableList;
046 import com.liferay.portal.kernel.util.Validator;
047 import com.liferay.portal.kernel.xml.Attribute;
048 import com.liferay.portal.kernel.xml.Document;
049 import com.liferay.portal.kernel.xml.Element;
050 import com.liferay.portal.kernel.xml.Node;
051 import com.liferay.portal.kernel.xml.SAXReaderUtil;
052 import com.liferay.portal.kernel.xml.XPath;
053 import com.liferay.portal.model.Group;
054 import com.liferay.portal.model.Layout;
055 import com.liferay.portal.model.LayoutConstants;
056 import com.liferay.portal.model.LayoutSet;
057 import com.liferay.portal.model.ModelHintsUtil;
058 import com.liferay.portal.model.User;
059 import com.liferay.portal.service.ImageLocalServiceUtil;
060 import com.liferay.portal.service.LayoutLocalServiceUtil;
061 import com.liferay.portal.service.UserLocalServiceUtil;
062 import com.liferay.portal.templateparser.Transformer;
063 import com.liferay.portal.theme.ThemeDisplay;
064 import com.liferay.portal.util.PortalUtil;
065 import com.liferay.portal.util.PortletKeys;
066 import com.liferay.portal.util.PropsUtil;
067 import com.liferay.portal.util.PropsValues;
068 import com.liferay.portal.util.WebKeys;
069 import com.liferay.portal.webserver.WebServerServletTokenUtil;
070 import com.liferay.portlet.PortletURLFactoryUtil;
071 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
072 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
073 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
074 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
075 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
076 import com.liferay.portlet.journal.NoSuchArticleException;
077 import com.liferay.portlet.journal.model.JournalArticle;
078 import com.liferay.portlet.journal.model.JournalFolder;
079 import com.liferay.portlet.journal.model.JournalFolderConstants;
080 import com.liferay.portlet.journal.model.JournalStructure;
081 import com.liferay.portlet.journal.model.JournalStructureAdapter;
082 import com.liferay.portlet.journal.model.JournalStructureConstants;
083 import com.liferay.portlet.journal.model.JournalTemplate;
084 import com.liferay.portlet.journal.model.JournalTemplateAdapter;
085 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
086 import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
087 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
088 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
089 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
090 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
091 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
092 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
093 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
094 import com.liferay.util.ContentUtil;
095 import com.liferay.util.FiniteUniqueStack;
096
097 import java.util.ArrayList;
098 import java.util.Collections;
099 import java.util.Date;
100 import java.util.HashMap;
101 import java.util.Iterator;
102 import java.util.List;
103 import java.util.Map;
104 import java.util.Stack;
105 import java.util.regex.Pattern;
106
107 import javax.portlet.PortletPreferences;
108 import javax.portlet.PortletRequest;
109 import javax.portlet.PortletSession;
110 import javax.portlet.PortletURL;
111 import javax.portlet.RenderResponse;
112
113 import javax.servlet.http.HttpServletRequest;
114
115
122 public class JournalUtil {
123
124 public static final int MAX_STACK_SIZE = 20;
125
126 public static void addAllReservedEls(
127 Element rootElement, Map<String, String> tokens, JournalArticle article,
128 String languageId, ThemeDisplay themeDisplay) {
129
130 JournalUtil.addReservedEl(
131 rootElement, tokens, JournalStructureConstants.RESERVED_ARTICLE_ID,
132 article.getArticleId());
133
134 JournalUtil.addReservedEl(
135 rootElement, tokens,
136 JournalStructureConstants.RESERVED_ARTICLE_VERSION,
137 article.getVersion());
138
139 JournalUtil.addReservedEl(
140 rootElement, tokens,
141 JournalStructureConstants.RESERVED_ARTICLE_TITLE,
142 article.getTitle(languageId));
143
144 JournalUtil.addReservedEl(
145 rootElement, tokens,
146 JournalStructureConstants.RESERVED_ARTICLE_URL_TITLE,
147 article.getUrlTitle());
148
149 JournalUtil.addReservedEl(
150 rootElement, tokens,
151 JournalStructureConstants.RESERVED_ARTICLE_DESCRIPTION,
152 article.getDescription(languageId));
153
154 JournalUtil.addReservedEl(
155 rootElement, tokens,
156 JournalStructureConstants.RESERVED_ARTICLE_TYPE, article.getType());
157
158 JournalUtil.addReservedEl(
159 rootElement, tokens,
160 JournalStructureConstants.RESERVED_ARTICLE_CREATE_DATE,
161 article.getCreateDate());
162
163 JournalUtil.addReservedEl(
164 rootElement, tokens,
165 JournalStructureConstants.RESERVED_ARTICLE_MODIFIED_DATE,
166 article.getModifiedDate());
167
168 if (article.getDisplayDate() != null) {
169 JournalUtil.addReservedEl(
170 rootElement, tokens,
171 JournalStructureConstants.RESERVED_ARTICLE_DISPLAY_DATE,
172 article.getDisplayDate());
173 }
174
175 String smallImageURL = StringPool.BLANK;
176
177 if (Validator.isNotNull(article.getSmallImageURL())) {
178 smallImageURL = article.getSmallImageURL();
179 }
180 else if ((themeDisplay != null) && article.isSmallImage()) {
181 StringBundler sb = new StringBundler(5);
182
183 sb.append(themeDisplay.getPathImage());
184 sb.append("/journal/article?img_id=");
185 sb.append(article.getSmallImageId());
186 sb.append("&t=");
187 sb.append(
188 WebServerServletTokenUtil.getToken(article.getSmallImageId()));
189
190 smallImageURL = sb.toString();
191 }
192
193 JournalUtil.addReservedEl(
194 rootElement, tokens,
195 JournalStructureConstants.RESERVED_ARTICLE_SMALL_IMAGE_URL,
196 smallImageURL);
197
198 String[] assetTagNames = new String[0];
199
200 try {
201 assetTagNames = AssetTagLocalServiceUtil.getTagNames(
202 JournalArticle.class.getName(), article.getResourcePrimKey());
203 }
204 catch (SystemException se) {
205 }
206
207 JournalUtil.addReservedEl(
208 rootElement, tokens,
209 JournalStructureConstants.RESERVED_ARTICLE_ASSET_TAG_NAMES,
210 StringUtil.merge(assetTagNames));
211
212 JournalUtil.addReservedEl(
213 rootElement, tokens,
214 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_ID,
215 String.valueOf(article.getUserId()));
216
217 String userName = StringPool.BLANK;
218 String userEmailAddress = StringPool.BLANK;
219 String userComments = StringPool.BLANK;
220 String userJobTitle = StringPool.BLANK;
221
222 User user = null;
223
224 try {
225 user = UserLocalServiceUtil.getUserById(article.getUserId());
226
227 userName = user.getFullName();
228 userEmailAddress = user.getEmailAddress();
229 userComments = user.getComments();
230 userJobTitle = user.getJobTitle();
231 }
232 catch (PortalException pe) {
233 }
234 catch (SystemException se) {
235 }
236
237 JournalUtil.addReservedEl(
238 rootElement, tokens,
239 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_NAME, userName);
240
241 JournalUtil.addReservedEl(
242 rootElement, tokens,
243 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_EMAIL_ADDRESS,
244 userEmailAddress);
245
246 JournalUtil.addReservedEl(
247 rootElement, tokens,
248 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_COMMENTS,
249 userComments);
250
251 JournalUtil.addReservedEl(
252 rootElement, tokens,
253 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_JOB_TITLE,
254 userJobTitle);
255 }
256
257 public static void addPortletBreadcrumbEntries(
258 JournalArticle article, HttpServletRequest request,
259 RenderResponse renderResponse)
260 throws Exception {
261
262 JournalFolder folder = article.getFolder();
263
264 if (folder.getFolderId() !=
265 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
266
267 addPortletBreadcrumbEntries(folder, request, renderResponse);
268 }
269
270 JournalArticle unescapedArticle = article.toUnescapedModel();
271
272 PortletURL portletURL = renderResponse.createRenderURL();
273
274 portletURL.setParameter("struts_action", "/article/view_article");
275 portletURL.setParameter(
276 "groupId", String.valueOf(article.getGroupId()));
277 portletURL.setParameter(
278 "articleId", String.valueOf(article.getArticleId()));
279
280 PortalUtil.addPortletBreadcrumbEntry(
281 request, unescapedArticle.getTitle(), portletURL.toString());
282 }
283
284 public static void addPortletBreadcrumbEntries(
285 JournalFolder folder, HttpServletRequest request,
286 LiferayPortletResponse liferayPortletResponse)
287 throws Exception {
288
289 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
290 com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
291
292 String strutsAction = ParamUtil.getString(request, "struts_action");
293
294 PortletURL portletURL = liferayPortletResponse.createRenderURL();
295
296 if (strutsAction.equals("/journal/select_folder")) {
297 portletURL.setParameter("struts_action", "/journal/select_folder");
298 portletURL.setWindowState(LiferayWindowState.POP_UP);
299
300 PortalUtil.addPortletBreadcrumbEntry(
301 request, themeDisplay.translate("home"), portletURL.toString());
302 }
303 else {
304 portletURL.setParameter("struts_action", "/journal/view");
305
306 Map<String, Object> data = new HashMap<String, Object>();
307
308 data.put("direction-right", Boolean.TRUE.toString());
309 data.put(
310 "folder-id", JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID);
311
312 PortalUtil.addPortletBreadcrumbEntry(
313 request, themeDisplay.translate("home"), portletURL.toString(),
314 data);
315 }
316
317 if (folder == null) {
318 return;
319 }
320
321 List<JournalFolder> ancestorFolders = folder.getAncestors();
322
323 Collections.reverse(ancestorFolders);
324
325 for (JournalFolder ancestorFolder : ancestorFolders) {
326 portletURL.setParameter(
327 "folderId", String.valueOf(ancestorFolder.getFolderId()));
328
329 Map<String, Object> data = new HashMap<String, Object>();
330
331 data.put("direction-right", Boolean.TRUE.toString());
332 data.put("folder-id", ancestorFolder.getFolderId());
333
334 PortalUtil.addPortletBreadcrumbEntry(
335 request, ancestorFolder.getName(), portletURL.toString(), data);
336 }
337
338 portletURL.setParameter(
339 "folderId", String.valueOf(folder.getFolderId()));
340
341 if (folder.getFolderId() !=
342 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
343
344 JournalFolder unescapedFolder = folder.toUnescapedModel();
345
346 Map<String, Object> data = new HashMap<String, Object>();
347
348 data.put("direction-right", Boolean.TRUE.toString());
349 data.put("folder-id", folder.getFolderId());
350
351 PortalUtil.addPortletBreadcrumbEntry(
352 request, unescapedFolder.getName(), portletURL.toString(),
353 data);
354 }
355 }
356
357 public static void addPortletBreadcrumbEntries(
358 JournalFolder folder, HttpServletRequest request,
359 RenderResponse renderResponse)
360 throws Exception {
361
362 LiferayPortletResponse liferayPortletResponse =
363 (LiferayPortletResponse)renderResponse;
364
365 addPortletBreadcrumbEntries(folder, request, liferayPortletResponse);
366 }
367
368 public static void addPortletBreadcrumbEntries(
369 long folderId, HttpServletRequest request,
370 RenderResponse renderResponse)
371 throws Exception {
372
373 if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
374 return;
375 }
376
377 JournalFolder folder = JournalFolderLocalServiceUtil.getFolder(
378 folderId);
379
380 addPortletBreadcrumbEntries(folder, request, renderResponse);
381 }
382
383 public static void addRecentArticle(
384 PortletRequest portletRequest, JournalArticle article) {
385
386 if (article != null) {
387 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
388
389 stack.push(article);
390 }
391 }
392
393 public static void addRecentDDMStructure(
394 PortletRequest portletRequest, DDMStructure ddmStructure) {
395
396 if (ddmStructure != null) {
397 Stack<DDMStructure> stack = getRecentDDMStructures(portletRequest);
398
399 stack.push(ddmStructure);
400 }
401 }
402
403 public static void addRecentDDMTemplate(
404 PortletRequest portletRequest, DDMTemplate ddmTemplate) {
405
406 if (ddmTemplate != null) {
407 Stack<DDMTemplate> stack = getRecentDDMTemplates(portletRequest);
408
409 stack.push(ddmTemplate);
410 }
411 }
412
413 public static void addReservedEl(
414 Element rootElement, Map<String, String> tokens, String name,
415 Date value) {
416
417 addReservedEl(rootElement, tokens, name, Time.getRFC822(value));
418 }
419
420 public static void addReservedEl(
421 Element rootElement, Map<String, String> tokens, String name,
422 double value) {
423
424 addReservedEl(rootElement, tokens, name, String.valueOf(value));
425 }
426
427 public static void addReservedEl(
428 Element rootElement, Map<String, String> tokens, String name,
429 String value) {
430
431
432
433 if (rootElement != null) {
434 Element dynamicElementElement = SAXReaderUtil.createElement(
435 "dynamic-element");
436
437 Attribute nameAttribute = SAXReaderUtil.createAttribute(
438 dynamicElementElement, "name", name);
439
440 dynamicElementElement.add(nameAttribute);
441
442 Attribute typeAttribute = SAXReaderUtil.createAttribute(
443 dynamicElementElement, "type", "text");
444
445 dynamicElementElement.add(typeAttribute);
446
447 Element dynamicContentElement = SAXReaderUtil.createElement(
448 "dynamic-content");
449
450
451 dynamicContentElement.setText(value);
452
453 dynamicElementElement.add(dynamicContentElement);
454
455 rootElement.add(dynamicElementElement);
456 }
457
458
459
460 tokens.put(
461 StringUtil.replace(name, CharPool.DASH, CharPool.UNDERLINE), value);
462 }
463
464 public static String formatVM(String vm) {
465 return vm;
466 }
467
468 public static String getAbsolutePath(
469 PortletRequest portletRequest, long folderId)
470 throws PortalException, SystemException {
471
472 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
473 WebKeys.THEME_DISPLAY);
474
475 if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
476 return themeDisplay.translate("home");
477 }
478
479 JournalFolder folder = JournalFolderLocalServiceUtil.getFolder(
480 folderId);
481
482 List<JournalFolder> folders = folder.getAncestors();
483
484 Collections.reverse(folders);
485
486 StringBundler sb = new StringBundler((folders.size() * 3) + 5);
487
488 sb.append(themeDisplay.translate("home"));
489 sb.append(StringPool.SPACE);
490
491 for (JournalFolder curFolder : folders) {
492 sb.append("\u00bb");
493 sb.append(StringPool.SPACE);
494 sb.append(curFolder.getName());
495 }
496
497 sb.append("\u00bb");
498 sb.append(StringPool.SPACE);
499 sb.append(folder.getName());
500
501 return sb.toString();
502 }
503
504 public static OrderByComparator getArticleOrderByComparator(
505 String orderByCol, String orderByType) {
506
507 boolean orderByAsc = false;
508
509 if (orderByType.equals("asc")) {
510 orderByAsc = true;
511 }
512
513 OrderByComparator orderByComparator = null;
514
515 if (orderByCol.equals("create-date")) {
516 orderByComparator = new ArticleCreateDateComparator(orderByAsc);
517 }
518 else if (orderByCol.equals("display-date")) {
519 orderByComparator = new ArticleDisplayDateComparator(orderByAsc);
520 }
521 else if (orderByCol.equals("id")) {
522 orderByComparator = new ArticleIDComparator(orderByAsc);
523 }
524 else if (orderByCol.equals("modified-date")) {
525 orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
526 }
527 else if (orderByCol.equals("review-date")) {
528 orderByComparator = new ArticleReviewDateComparator(orderByAsc);
529 }
530 else if (orderByCol.equals("title")) {
531 orderByComparator = new ArticleTitleComparator(orderByAsc);
532 }
533 else if (orderByCol.equals("version")) {
534 orderByComparator = new ArticleVersionComparator(orderByAsc);
535 }
536
537 return orderByComparator;
538 }
539
540 public static Tuple getArticles(Hits hits)
541 throws PortalException, SystemException {
542
543 List<JournalArticle> articles = new ArrayList<JournalArticle>();
544 boolean corruptIndex = false;
545
546 List<com.liferay.portal.kernel.search.Document> documents =
547 hits.toList();
548
549 for (com.liferay.portal.kernel.search.Document document : documents) {
550 long groupId = GetterUtil.getLong(document.get(Field.GROUP_ID));
551 String articleId = document.get("articleId");
552
553 try {
554 JournalArticle article =
555 JournalArticleLocalServiceUtil.getArticle(
556 groupId, articleId);
557
558 articles.add(article);
559 }
560 catch (NoSuchArticleException nsae) {
561 corruptIndex = true;
562
563 Indexer indexer = IndexerRegistryUtil.getIndexer(
564 JournalArticle.class);
565
566 long companyId = GetterUtil.getLong(
567 document.get(Field.COMPANY_ID));
568
569 indexer.delete(companyId, document.getUID());
570 }
571 }
572
573 return new Tuple(articles, corruptIndex);
574 }
575
576 public static String getEmailArticleAddedBody(
577 PortletPreferences preferences) {
578
579 String emailArticleAddedBody = preferences.getValue(
580 "emailArticleAddedBody", StringPool.BLANK);
581
582 if (Validator.isNotNull(emailArticleAddedBody)) {
583 return emailArticleAddedBody;
584 }
585 else {
586 return ContentUtil.get(
587 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_ADDED_BODY));
588 }
589 }
590
591 public static boolean getEmailArticleAddedEnabled(
592 PortletPreferences preferences) {
593
594 String emailArticleAddedEnabled = preferences.getValue(
595 "emailArticleAddedEnabled", StringPool.BLANK);
596
597 if (Validator.isNotNull(emailArticleAddedEnabled)) {
598 return GetterUtil.getBoolean(emailArticleAddedEnabled);
599 }
600 else {
601 return GetterUtil.getBoolean(
602 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_ADDED_ENABLED));
603 }
604 }
605
606 public static String getEmailArticleAddedSubject(
607 PortletPreferences preferences) {
608
609 String emailArticleAddedSubject = preferences.getValue(
610 "emailArticleAddedSubject", StringPool.BLANK);
611
612 if (Validator.isNotNull(emailArticleAddedSubject)) {
613 return emailArticleAddedSubject;
614 }
615 else {
616 return ContentUtil.get(
617 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_ADDED_SUBJECT));
618 }
619 }
620
621 public static String getEmailArticleApprovalDeniedBody(
622 PortletPreferences preferences) {
623
624 String emailArticleApprovalDeniedBody = preferences.getValue(
625 "emailArticleApprovalDeniedBody", StringPool.BLANK);
626
627 if (Validator.isNotNull(emailArticleApprovalDeniedBody)) {
628 return emailArticleApprovalDeniedBody;
629 }
630 else {
631 return ContentUtil.get(
632 PropsUtil.get(
633 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_BODY));
634 }
635 }
636
637 public static boolean getEmailArticleApprovalDeniedEnabled(
638 PortletPreferences preferences) {
639
640 String emailArticleApprovalDeniedEnabled = preferences.getValue(
641 "emailArticleApprovalDeniedEnabled", StringPool.BLANK);
642
643 if (Validator.isNotNull(emailArticleApprovalDeniedEnabled)) {
644 return GetterUtil.getBoolean(emailArticleApprovalDeniedEnabled);
645 }
646 else {
647 return GetterUtil.getBoolean(
648 PropsUtil.get(
649 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_ENABLED));
650 }
651 }
652
653 public static String getEmailArticleApprovalDeniedSubject(
654 PortletPreferences preferences) {
655
656 String emailArticleApprovalDeniedSubject = preferences.getValue(
657 "emailArticleApprovalDeniedSubject", StringPool.BLANK);
658
659 if (Validator.isNotNull(emailArticleApprovalDeniedSubject)) {
660 return emailArticleApprovalDeniedSubject;
661 }
662 else {
663 return ContentUtil.get(
664 PropsUtil.get(
665 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_SUBJECT));
666 }
667 }
668
669 public static String getEmailArticleApprovalGrantedBody(
670 PortletPreferences preferences) {
671
672 String emailArticleApprovalGrantedBody = preferences.getValue(
673 "emailArticleApprovalGrantedBody", StringPool.BLANK);
674
675 if (Validator.isNotNull(emailArticleApprovalGrantedBody)) {
676 return emailArticleApprovalGrantedBody;
677 }
678 else {
679 return ContentUtil.get(
680 PropsUtil.get(
681 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_BODY));
682 }
683 }
684
685 public static boolean getEmailArticleApprovalGrantedEnabled(
686 PortletPreferences preferences) {
687
688 String emailArticleApprovalGrantedEnabled = preferences.getValue(
689 "emailArticleApprovalGrantedEnabled", StringPool.BLANK);
690
691 if (Validator.isNotNull(emailArticleApprovalGrantedEnabled)) {
692 return GetterUtil.getBoolean(emailArticleApprovalGrantedEnabled);
693 }
694 else {
695 return GetterUtil.getBoolean(
696 PropsUtil.get(
697 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_ENABLED));
698 }
699 }
700
701 public static String getEmailArticleApprovalGrantedSubject(
702 PortletPreferences preferences) {
703
704 String emailArticleApprovalGrantedSubject = preferences.getValue(
705 "emailArticleApprovalGrantedSubject", StringPool.BLANK);
706
707 if (Validator.isNotNull(emailArticleApprovalGrantedSubject)) {
708 return emailArticleApprovalGrantedSubject;
709 }
710 else {
711 return ContentUtil.get(
712 PropsUtil.get(
713 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_SUBJECT));
714 }
715 }
716
717 public static String getEmailArticleApprovalRequestedBody(
718 PortletPreferences preferences) {
719
720 String emailArticleApprovalRequestedBody = preferences.getValue(
721 "emailArticleApprovalRequestedBody", StringPool.BLANK);
722
723 if (Validator.isNotNull(emailArticleApprovalRequestedBody)) {
724 return emailArticleApprovalRequestedBody;
725 }
726 else {
727 return ContentUtil.get(
728 PropsUtil.get(
729 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_BODY));
730 }
731 }
732
733 public static boolean getEmailArticleApprovalRequestedEnabled(
734 PortletPreferences preferences) {
735
736 String emailArticleApprovalRequestedEnabled = preferences.getValue(
737 "emailArticleApprovalRequestedEnabled", StringPool.BLANK);
738
739 if (Validator.isNotNull(emailArticleApprovalRequestedEnabled)) {
740 return GetterUtil.getBoolean(emailArticleApprovalRequestedEnabled);
741 }
742 else {
743 return GetterUtil.getBoolean(
744 PropsUtil.get(
745 PropsKeys.
746 JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_ENABLED));
747 }
748 }
749
750 public static String getEmailArticleApprovalRequestedSubject(
751 PortletPreferences preferences) {
752
753 String emailArticleApprovalRequestedSubject = preferences.getValue(
754 "emailArticleApprovalRequestedSubject", StringPool.BLANK);
755
756 if (Validator.isNotNull(emailArticleApprovalRequestedSubject)) {
757 return emailArticleApprovalRequestedSubject;
758 }
759 else {
760 return ContentUtil.get(
761 PropsUtil.get(
762 PropsKeys.
763 JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_SUBJECT));
764 }
765 }
766
767 public static String getEmailArticleReviewBody(
768 PortletPreferences preferences) {
769
770 String emailArticleReviewBody = preferences.getValue(
771 "emailArticleReviewBody", StringPool.BLANK);
772
773 if (Validator.isNotNull(emailArticleReviewBody)) {
774 return emailArticleReviewBody;
775 }
776 else {
777 return ContentUtil.get(
778 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_BODY));
779 }
780 }
781
782 public static boolean getEmailArticleReviewEnabled(
783 PortletPreferences preferences) {
784
785 String emailArticleReviewEnabled = preferences.getValue(
786 "emailArticleReviewEnabled", StringPool.BLANK);
787
788 if (Validator.isNotNull(emailArticleReviewEnabled)) {
789 return GetterUtil.getBoolean(emailArticleReviewEnabled);
790 }
791 else {
792 return GetterUtil.getBoolean(
793 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_ENABLED));
794 }
795 }
796
797 public static String getEmailArticleReviewSubject(
798 PortletPreferences preferences) {
799
800 String emailArticleReviewSubject = preferences.getValue(
801 "emailArticleReviewSubject", StringPool.BLANK);
802
803 if (Validator.isNotNull(emailArticleReviewSubject)) {
804 return emailArticleReviewSubject;
805 }
806 else {
807 return ContentUtil.get(
808 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_SUBJECT));
809 }
810 }
811
812 public static String getEmailArticleUpdatedBody(
813 PortletPreferences preferences) {
814
815 String emailArticleUpdatedBody = preferences.getValue(
816 "emailArticleUpdatedBody", StringPool.BLANK);
817
818 if (Validator.isNotNull(emailArticleUpdatedBody)) {
819 return emailArticleUpdatedBody;
820 }
821 else {
822 return ContentUtil.get(
823 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_UPDATED_BODY));
824 }
825 }
826
827 public static boolean getEmailArticleUpdatedEnabled(
828 PortletPreferences preferences) {
829
830 String emailArticleUpdatedEnabled = preferences.getValue(
831 "emailArticleUpdatedEnabled", StringPool.BLANK);
832
833 if (Validator.isNotNull(emailArticleUpdatedEnabled)) {
834 return GetterUtil.getBoolean(emailArticleUpdatedEnabled);
835 }
836 else {
837 return GetterUtil.getBoolean(
838 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_UPDATED_ENABLED));
839 }
840 }
841
842 public static String getEmailArticleUpdatedSubject(
843 PortletPreferences preferences) {
844
845 String emailArticleUpdatedSubject = preferences.getValue(
846 "emailArticleUpdatedSubject", StringPool.BLANK);
847
848 if (Validator.isNotNull(emailArticleUpdatedSubject)) {
849 return emailArticleUpdatedSubject;
850 }
851 else {
852 return ContentUtil.get(
853 PropsUtil.get(PropsKeys.JOURNAL_EMAIL_ARTICLE_UPDATED_SUBJECT));
854 }
855 }
856
857 public static String getEmailFromAddress(
858 PortletPreferences preferences, long companyId)
859 throws SystemException {
860
861 return PortalUtil.getEmailFromAddress(
862 preferences, companyId, PropsValues.JOURNAL_EMAIL_FROM_ADDRESS);
863 }
864
865 public static String getEmailFromName(
866 PortletPreferences preferences, long companyId)
867 throws SystemException {
868
869 return PortalUtil.getEmailFromName(
870 preferences, companyId, PropsValues.JOURNAL_EMAIL_FROM_NAME);
871 }
872
873 public static String getJournalControlPanelLink(
874 PortletRequest portletRequest, long folderId)
875 throws PortalException, SystemException {
876
877 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
878 WebKeys.THEME_DISPLAY);
879
880 PortletURL portletURL = PortletURLFactoryUtil.create(
881 portletRequest, PortletKeys.JOURNAL,
882 PortalUtil.getControlPanelPlid(themeDisplay.getCompanyId()),
883 PortletRequest.RENDER_PHASE);
884
885 portletURL.setParameter("struts_action", "/journal/view");
886 portletURL.setParameter("folderId", String.valueOf(folderId));
887
888 return portletURL.toString();
889 }
890
891 public static long getPreviewPlid(
892 JournalArticle article, ThemeDisplay themeDisplay)
893 throws Exception {
894
895 if ((article != null) && Validator.isNotNull(article.getLayoutUuid())) {
896 Layout layout =
897 LayoutLocalServiceUtil.getLayoutByUuidAndCompanyId(
898 article.getLayoutUuid(), themeDisplay.getCompanyId());
899
900 return layout.getPlid();
901 }
902
903 Layout layout = LayoutLocalServiceUtil.fetchFirstLayout(
904 themeDisplay.getScopeGroupId(), false,
905 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
906
907 if (layout == null) {
908 layout = LayoutLocalServiceUtil.fetchFirstLayout(
909 themeDisplay.getScopeGroupId(), true,
910 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
911 }
912
913 if (layout != null) {
914 return layout.getPlid();
915 }
916
917 return themeDisplay.getPlid();
918 }
919
920 public static Stack<JournalArticle> getRecentArticles(
921 PortletRequest portletRequest) {
922
923 PortletSession portletSession = portletRequest.getPortletSession();
924
925 Stack<JournalArticle> recentArticles =
926 (Stack<JournalArticle>)portletSession.getAttribute(
927 WebKeys.JOURNAL_RECENT_ARTICLES);
928
929 if (recentArticles == null) {
930 recentArticles = new FiniteUniqueStack<JournalArticle>(
931 MAX_STACK_SIZE);
932
933 portletSession.setAttribute(
934 WebKeys.JOURNAL_RECENT_ARTICLES, recentArticles);
935 }
936
937 return recentArticles;
938 }
939
940 public static Stack<DDMStructure> getRecentDDMStructures(
941 PortletRequest portletRequest) {
942
943 PortletSession portletSession = portletRequest.getPortletSession();
944
945 Stack<DDMStructure> recentDDMStructures =
946 (Stack<DDMStructure>)portletSession.getAttribute(
947 WebKeys.JOURNAL_RECENT_DYNAMIC_DATA_MAPPING_STRUCTURES);
948
949 if (recentDDMStructures == null) {
950 recentDDMStructures = new FiniteUniqueStack<DDMStructure>(
951 MAX_STACK_SIZE);
952
953 portletSession.setAttribute(
954 WebKeys.JOURNAL_RECENT_DYNAMIC_DATA_MAPPING_STRUCTURES,
955 recentDDMStructures);
956 }
957
958 return recentDDMStructures;
959 }
960
961 public static Stack<DDMTemplate> getRecentDDMTemplates(
962 PortletRequest portletRequest) {
963
964 PortletSession portletSession = portletRequest.getPortletSession();
965
966 Stack<DDMTemplate> recentDDMTemplates =
967 (Stack<DDMTemplate>)portletSession.getAttribute(
968 WebKeys.JOURNAL_RECENT_DYNAMIC_DATA_MAPPING_TEMPLATES);
969
970 if (recentDDMTemplates == null) {
971 recentDDMTemplates = new FiniteUniqueStack<DDMTemplate>(
972 MAX_STACK_SIZE);
973
974 portletSession.setAttribute(
975 WebKeys.JOURNAL_RECENT_DYNAMIC_DATA_MAPPING_TEMPLATES,
976 recentDDMTemplates);
977 }
978
979 return recentDDMTemplates;
980 }
981
982 public static long[] getStructureClassPKs(
983 long[] groupIds, String structureId)
984 throws SystemException {
985
986 List<Long> classPKs = new ArrayList<Long>();
987
988 for (long groupId : groupIds) {
989 @SuppressWarnings("deprecation")
990 JournalStructure structure =
991 com.liferay.portlet.journal.service.
992 JournalStructureLocalServiceUtil.fetchStructure(
993 groupId, structureId);
994
995 if (structure != null) {
996 classPKs.add(structure.getId());
997 }
998 }
999
1000 return ArrayUtil.toLongArray(classPKs);
1001 }
1002
1003 public static String getTemplateScript(
1004 DDMTemplate ddmTemplate, Map<String, String> tokens, String languageId,
1005 boolean transform) {
1006
1007 String script = ddmTemplate.getScript();
1008
1009 if (!transform) {
1010 return script;
1011 }
1012
1013 String[] transformerListenerClassNames = PropsUtil.getArray(
1014 PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
1015
1016 for (String transformerListenerClassName :
1017 transformerListenerClassNames) {
1018
1019 TransformerListener transformerListener = null;
1020
1021 try {
1022 transformerListener =
1023 (TransformerListener)InstanceFactory.newInstance(
1024 transformerListenerClassName);
1025
1026 continue;
1027 }
1028 catch (Exception e) {
1029 _log.error(e, e);
1030 }
1031
1032 script = transformerListener.onScript(
1033 script, null, languageId, tokens);
1034 }
1035
1036 return script;
1037 }
1038
1039 public static String getTemplateScript(
1040 long groupId, String ddmTemplateKey, Map<String, String> tokens,
1041 String languageId)
1042 throws PortalException, SystemException {
1043
1044 return getTemplateScript(
1045 groupId, ddmTemplateKey, tokens, languageId, true);
1046 }
1047
1048 public static String getTemplateScript(
1049 long groupId, String ddmTemplateKey, Map<String, String> tokens,
1050 String languageId, boolean transform)
1051 throws PortalException, SystemException {
1052
1053 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
1054 groupId, PortalUtil.getClassNameId(DDMStructure.class),
1055 ddmTemplateKey, true);
1056
1057 return getTemplateScript(ddmTemplate, tokens, languageId, transform);
1058 }
1059
1060 public static Map<String, String> getTokens(
1061 long articleGroupId, ThemeDisplay themeDisplay)
1062 throws PortalException, SystemException {
1063
1064 return getTokens(articleGroupId, themeDisplay, null);
1065 }
1066
1067 public static Map<String, String> getTokens(
1068 long articleGroupId, ThemeDisplay themeDisplay, String xmlRequest)
1069 throws PortalException, SystemException {
1070
1071 Map<String, String> tokens = new HashMap<String, String>();
1072
1073 if (themeDisplay != null) {
1074 _populateTokens(tokens, articleGroupId, themeDisplay);
1075 }
1076 else if (Validator.isNotNull(xmlRequest)) {
1077 try {
1078 _populateTokens(tokens, articleGroupId, xmlRequest);
1079 }
1080 catch (Exception e) {
1081 if (_log.isWarnEnabled()) {
1082 _log.warn(e, e);
1083 }
1084 }
1085 }
1086
1087 return tokens;
1088 }
1089
1090 public static String getUrlTitle(long id, String title) {
1091 if (title == null) {
1092 return String.valueOf(id);
1093 }
1094
1095 title = StringUtil.toLowerCase(title.trim());
1096
1097 if (Validator.isNull(title) || Validator.isNumber(title) ||
1098 title.equals("rss")) {
1099
1100 title = String.valueOf(id);
1101 }
1102 else {
1103 title = FriendlyURLNormalizerUtil.normalize(
1104 title, _friendlyURLPattern);
1105 }
1106
1107 return ModelHintsUtil.trimString(
1108 JournalArticle.class.getName(), "urlTitle", title);
1109 }
1110
1111 public static String mergeArticleContent(
1112 String curContent, String newContent, boolean removeNullElements) {
1113
1114 try {
1115 Document curDocument = SAXReaderUtil.read(curContent);
1116 Document newDocument = SAXReaderUtil.read(newContent);
1117
1118 Element curRootElement = curDocument.getRootElement();
1119 Element newRootElement = newDocument.getRootElement();
1120
1121 curRootElement.addAttribute(
1122 "default-locale",
1123 newRootElement.attributeValue("default-locale"));
1124 curRootElement.addAttribute(
1125 "available-locales",
1126 newRootElement.attributeValue("available-locales"));
1127
1128 _mergeArticleContentUpdate(
1129 curDocument, newRootElement,
1130 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault()));
1131
1132 if (removeNullElements) {
1133 _mergeArticleContentDelete(curRootElement, newDocument);
1134 }
1135
1136 curContent = DDMXMLUtil.formatXML(curDocument);
1137 }
1138 catch (Exception e) {
1139 _log.error(e, e);
1140 }
1141
1142 return curContent;
1143 }
1144
1145 public static void removeArticleLocale(Element element, String languageId)
1146 throws PortalException, SystemException {
1147
1148 for (Element dynamicElementElement :
1149 element.elements("dynamic-element")) {
1150
1151 for (Element dynamicContentElement :
1152 dynamicElementElement.elements("dynamic-content")) {
1153
1154 String curLanguageId = GetterUtil.getString(
1155 dynamicContentElement.attributeValue("language-id"));
1156
1157 if (curLanguageId.equals(languageId)) {
1158 long id = GetterUtil.getLong(
1159 dynamicContentElement.attributeValue("id"));
1160
1161 if (id > 0) {
1162 ImageLocalServiceUtil.deleteImage(id);
1163 }
1164
1165 dynamicContentElement.detach();
1166 }
1167 }
1168
1169 removeArticleLocale(dynamicElementElement, languageId);
1170 }
1171 }
1172
1173 public static String removeArticleLocale(
1174 String content, String languageId) {
1175
1176 try {
1177 Document document = SAXReaderUtil.read(content);
1178
1179 Element rootElement = document.getRootElement();
1180
1181 String availableLocales = rootElement.attributeValue(
1182 "available-locales");
1183
1184 if (availableLocales == null) {
1185 return content;
1186 }
1187
1188 availableLocales = StringUtil.remove(availableLocales, languageId);
1189
1190 if (availableLocales.endsWith(",")) {
1191 availableLocales = availableLocales.substring(
1192 0, availableLocales.length() - 1);
1193 }
1194
1195 rootElement.addAttribute("available-locales", availableLocales);
1196
1197 removeArticleLocale(rootElement, languageId);
1198
1199 content = DDMXMLUtil.formatXML(document);
1200 }
1201 catch (Exception e) {
1202 _log.error(e, e);
1203 }
1204
1205 return content;
1206 }
1207
1208 public static String removeOldContent(String content, String xsd) {
1209 try {
1210 Document contentDoc = SAXReaderUtil.read(content);
1211 Document xsdDoc = SAXReaderUtil.read(xsd);
1212
1213 Element contentRoot = contentDoc.getRootElement();
1214
1215 Stack<String> path = new Stack<String>();
1216
1217 path.push(contentRoot.getName());
1218
1219 _removeOldContent(path, contentRoot, xsdDoc);
1220
1221 content = DDMXMLUtil.formatXML(contentDoc);
1222 }
1223 catch (Exception e) {
1224 _log.error(e, e);
1225 }
1226
1227 return content;
1228 }
1229
1230 public static void removeRecentArticle(
1231 PortletRequest portletRequest, String articleId) {
1232
1233 removeRecentArticle(portletRequest, articleId, 0);
1234 }
1235
1236 public static void removeRecentArticle(
1237 PortletRequest portletRequest, String articleId, double version) {
1238
1239 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
1240
1241 Iterator<JournalArticle> itr = stack.iterator();
1242
1243 while (itr.hasNext()) {
1244 JournalArticle journalArticle = itr.next();
1245
1246 if (journalArticle.getArticleId().equals(articleId) &&
1247 ((journalArticle.getVersion() == version) ||
1248 (version == 0))) {
1249
1250 itr.remove();
1251 }
1252 }
1253 }
1254
1255 public static void removeRecentDDMStructure(
1256 PortletRequest portletRequest, String ddmStructureKey) {
1257
1258 Stack<DDMStructure> stack = getRecentDDMStructures(portletRequest);
1259
1260 Iterator<DDMStructure> itr = stack.iterator();
1261
1262 while (itr.hasNext()) {
1263 DDMStructure ddmStructure = itr.next();
1264
1265 if (ddmStructureKey.equals(ddmStructure.getStructureKey())) {
1266 itr.remove();
1267
1268 break;
1269 }
1270 }
1271 }
1272
1273 public static void removeRecentDDMTemplate(
1274 PortletRequest portletRequest, String ddmTemplateKey) {
1275
1276 Stack<DDMTemplate> stack = getRecentDDMTemplates(portletRequest);
1277
1278 Iterator<DDMTemplate> itr = stack.iterator();
1279
1280 while (itr.hasNext()) {
1281 DDMTemplate ddmTemplate = itr.next();
1282
1283 if (ddmTemplateKey.equals(ddmTemplate.getTemplateKey())) {
1284 itr.remove();
1285
1286 break;
1287 }
1288 }
1289 }
1290
1291 public static List<JournalStructure> toJournalStructures(
1292 List<DDMStructure> ddmStructures)
1293 throws SystemException {
1294
1295 List<JournalStructure> structures = new ArrayList<JournalStructure>();
1296
1297 for (DDMStructure ddmStructure : ddmStructures) {
1298 JournalStructure structure = new JournalStructureAdapter(
1299 ddmStructure);
1300
1301 structures.add(structure);
1302 }
1303
1304 return new UnmodifiableList<JournalStructure>(structures);
1305 }
1306
1307 public static List<JournalTemplate> toJournalTemplates(
1308 List<DDMTemplate> ddmTemplates) {
1309
1310 List<JournalTemplate> templates = new ArrayList<JournalTemplate>();
1311
1312 for (DDMTemplate ddmTemplate : ddmTemplates) {
1313 JournalTemplate template = new JournalTemplateAdapter(ddmTemplate);
1314
1315 templates.add(template);
1316 }
1317
1318 return new UnmodifiableList<JournalTemplate>(templates);
1319 }
1320
1321 public static String transform(
1322 ThemeDisplay themeDisplay, Map<String, String> tokens,
1323 String viewMode, String languageId, String xml, String script,
1324 String langType)
1325 throws Exception {
1326
1327 return _transformer.transform(
1328 themeDisplay, tokens, viewMode, languageId, xml, script, langType);
1329 }
1330
1331 private static void _addElementOptions(
1332 Element curContentElement, Element newContentElement) {
1333
1334 List<Element> newElementOptions = newContentElement.elements("option");
1335
1336 for (Element newElementOption : newElementOptions) {
1337 Element curElementOption = SAXReaderUtil.createElement("option");
1338
1339 curElementOption.addCDATA(newElementOption.getText());
1340
1341 curContentElement.add(curElementOption);
1342 }
1343 }
1344
1345 private static Element _getElementByInstanceId(
1346 Document document, String instanceId) {
1347
1348 XPath xPathSelector = SAXReaderUtil.createXPath(
1349 "
1350 HtmlUtil.escapeXPathAttribute(instanceId) + "]");
1351
1352 List<Node> nodes = xPathSelector.selectNodes(document);
1353
1354 if (nodes.size() == 1) {
1355 return (Element)nodes.get(0);
1356 }
1357 else {
1358 return null;
1359 }
1360 }
1361
1362 private static void _mergeArticleContentDelete(
1363 Element curParentElement, Document newDocument)
1364 throws Exception {
1365
1366 List<Element> curElements = curParentElement.elements(
1367 "dynamic-element");
1368
1369 for (int i = 0; i < curElements.size(); i++) {
1370 Element curElement = curElements.get(i);
1371
1372 _mergeArticleContentDelete(curElement, newDocument);
1373
1374 String instanceId = curElement.attributeValue("instance-id");
1375
1376 Element newElement = _getElementByInstanceId(
1377 newDocument, instanceId);
1378
1379 if (newElement == null) {
1380 curElement.detach();
1381 }
1382 }
1383 }
1384
1385 private static void _mergeArticleContentUpdate(
1386 Document curDocument, Element newParentElement, Element newElement,
1387 int pos, String defaultLocale)
1388 throws Exception {
1389
1390 _mergeArticleContentUpdate(curDocument, newElement, defaultLocale);
1391
1392 String instanceId = newElement.attributeValue("instance-id");
1393
1394 Element curElement = _getElementByInstanceId(curDocument, instanceId);
1395
1396 if (curElement != null) {
1397 _mergeArticleContentUpdate(curElement, newElement, defaultLocale);
1398 }
1399 else {
1400 String parentInstanceId = newParentElement.attributeValue(
1401 "instance-id");
1402
1403 if (Validator.isNull(parentInstanceId)) {
1404 Element curRoot = curDocument.getRootElement();
1405
1406 List<Element> curRootElements = curRoot.elements();
1407
1408 curRootElements.add(pos, newElement.createCopy());
1409 }
1410 else {
1411 Element curParentElement = _getElementByInstanceId(
1412 curDocument, parentInstanceId);
1413
1414 if (curParentElement != null) {
1415 List<Element> curParentElements =
1416 curParentElement.elements();
1417
1418 curParentElements.add(pos, newElement.createCopy());
1419 }
1420 }
1421 }
1422 }
1423
1424 private static void _mergeArticleContentUpdate(
1425 Document curDocument, Element newParentElement,
1426 String defaultLocale)
1427 throws Exception {
1428
1429 List<Element> newElements = newParentElement.elements(
1430 "dynamic-element");
1431
1432 for (int i = 0; i < newElements.size(); i++) {
1433 Element newElement = newElements.get(i);
1434
1435 _mergeArticleContentUpdate(
1436 curDocument, newParentElement, newElement, i, defaultLocale);
1437 }
1438 }
1439
1440 private static void _mergeArticleContentUpdate(
1441 Element curElement, Element newElement, String defaultLocale) {
1442
1443 Attribute curTypeAttribute = curElement.attribute("type");
1444 Attribute newTypeAttribute = newElement.attribute("type");
1445
1446 curTypeAttribute.setValue(newTypeAttribute.getValue());
1447
1448 Attribute curIndexTypeAttribute = curElement.attribute("index-type");
1449 Attribute newIndexTypeAttribute = newElement.attribute("index-type");
1450
1451 if (newIndexTypeAttribute != null) {
1452 if (curIndexTypeAttribute == null) {
1453 curElement.addAttribute(
1454 "index-type", newIndexTypeAttribute.getValue());
1455 }
1456 else {
1457 curIndexTypeAttribute.setValue(
1458 newIndexTypeAttribute.getValue());
1459 }
1460 }
1461
1462 List<Element> elements = newElement.elements("dynamic-content");
1463
1464 Element newContentElement = elements.get(0);
1465
1466 String newLanguageId = newContentElement.attributeValue("language-id");
1467 String newValue = newContentElement.getText();
1468
1469 String indexType = newElement.attributeValue("index-type");
1470
1471 if (Validator.isNotNull(indexType)) {
1472 curElement.addAttribute("index-type", indexType);
1473 }
1474
1475 List<Element> curContentElements = curElement.elements(
1476 "dynamic-content");
1477
1478 if (Validator.isNull(newLanguageId)) {
1479 for (Element curContentElement : curContentElements) {
1480 curContentElement.detach();
1481 }
1482
1483 Element curContentElement = SAXReaderUtil.createElement(
1484 "dynamic-content");
1485
1486 if (newContentElement.element("option") != null) {
1487 _addElementOptions(curContentElement, newContentElement);
1488 }
1489 else {
1490 curContentElement.addCDATA(newValue);
1491 }
1492
1493 curElement.add(curContentElement);
1494 }
1495 else {
1496 boolean alreadyExists = false;
1497
1498 for (Element curContentElement : curContentElements) {
1499 String curLanguageId = curContentElement.attributeValue(
1500 "language-id");
1501
1502 if (newLanguageId.equals(curLanguageId)) {
1503 alreadyExists = true;
1504
1505 curContentElement.clearContent();
1506
1507 if (newContentElement.element("option") != null) {
1508 _addElementOptions(
1509 curContentElement, newContentElement);
1510 }
1511 else {
1512 curContentElement.addCDATA(newValue);
1513 }
1514
1515 break;
1516 }
1517 }
1518
1519 if (!alreadyExists) {
1520 Element curContentElement = curContentElements.get(0);
1521
1522 String curLanguageId = curContentElement.attributeValue(
1523 "language-id");
1524
1525 if (Validator.isNull(curLanguageId)) {
1526 if (newLanguageId.equals(defaultLocale)) {
1527 curContentElement.clearContent();
1528
1529 if (newContentElement.element("option") != null) {
1530 _addElementOptions(
1531 curContentElement, newContentElement);
1532 }
1533 else {
1534 curContentElement.addCDATA(newValue);
1535 }
1536 }
1537 else {
1538 curElement.add(newContentElement.createCopy());
1539 }
1540
1541 curContentElement.addAttribute(
1542 "language-id", defaultLocale);
1543 }
1544 else {
1545 curElement.add(newContentElement.createCopy());
1546 }
1547 }
1548 }
1549 }
1550
1551 private static void _populateCustomTokens(Map<String, String> tokens) {
1552 if (_customTokens == null) {
1553 synchronized (JournalUtil.class) {
1554 _customTokens = new HashMap<String, String>();
1555
1556 for (String customToken :
1557 PropsValues.JOURNAL_ARTICLE_CUSTOM_TOKENS) {
1558
1559 String value = PropsUtil.get(
1560 PropsKeys.JOURNAL_ARTICLE_CUSTOM_TOKEN_VALUE,
1561 new Filter(customToken));
1562
1563 _customTokens.put(customToken, value);
1564 }
1565 }
1566 }
1567
1568 if (!_customTokens.isEmpty()) {
1569 tokens.putAll(_customTokens);
1570 }
1571 }
1572
1573 private static void _populateTokens(
1574 Map<String, String> tokens, long articleGroupId, String xmlRequest)
1575 throws Exception {
1576
1577 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1578
1579 Element rootElement = requestDocument.getRootElement();
1580
1581 Element themeDisplayElement = rootElement.element("theme-display");
1582
1583 Layout layout = LayoutLocalServiceUtil.getLayout(
1584 GetterUtil.getLong(themeDisplayElement.elementText("plid")));
1585
1586 Group group = layout.getGroup();
1587
1588 LayoutSet layoutSet = layout.getLayoutSet();
1589
1590 String friendlyUrlCurrent = null;
1591
1592 if (layout.isPublicLayout()) {
1593 friendlyUrlCurrent = themeDisplayElement.elementText(
1594 "path-friendly-url-public");
1595 }
1596 else if (group.isUserGroup()) {
1597 friendlyUrlCurrent = themeDisplayElement.elementText(
1598 "path-friendly-url-private-user");
1599 }
1600 else {
1601 friendlyUrlCurrent = themeDisplayElement.elementText(
1602 "path-friendly-url-private-group");
1603 }
1604
1605 String layoutSetFriendlyUrl = themeDisplayElement.elementText(
1606 "i18n-path");
1607
1608 String virtualHostname = layoutSet.getVirtualHostname();
1609
1610 if (Validator.isNull(virtualHostname) ||
1611 !virtualHostname.equals(
1612 themeDisplayElement.elementText("server-name"))) {
1613
1614 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1615 }
1616
1617 tokens.put("article_group_id", String.valueOf(articleGroupId));
1618 tokens.put("cdn_host", themeDisplayElement.elementText("cdn-host"));
1619 tokens.put("company_id", themeDisplayElement.elementText("company-id"));
1620 tokens.put("friendly_url_current", friendlyUrlCurrent);
1621 tokens.put(
1622 "friendly_url_private_group",
1623 themeDisplayElement.elementText("path-friendly-url-private-group"));
1624 tokens.put(
1625 "friendly_url_private_user",
1626 themeDisplayElement.elementText("path-friendly-url-private-user"));
1627 tokens.put(
1628 "friendly_url_public",
1629 themeDisplayElement.elementText("path-friendly-url-public"));
1630 tokens.put("group_friendly_url", group.getFriendlyURL());
1631 tokens.put("image_path", themeDisplayElement.elementText("path-image"));
1632 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1633 tokens.put("main_path", themeDisplayElement.elementText("path-main"));
1634 tokens.put(
1635 "portal_ctx", themeDisplayElement.elementText("path-context"));
1636 tokens.put(
1637 "portal_url",
1638 HttpUtil.removeProtocol(
1639 themeDisplayElement.elementText("url-portal")));
1640 tokens.put(
1641 "protocol",
1642 HttpUtil.getProtocol(
1643 themeDisplayElement.elementText("url-portal")));
1644 tokens.put(
1645 "root_path", themeDisplayElement.elementText("path-context"));
1646 tokens.put(
1647 "scope_group_id",
1648 themeDisplayElement.elementText("scope-group-id"));
1649 tokens.put(
1650 "site_group_id", themeDisplayElement.elementText("site-group-id"));
1651 tokens.put(
1652 "theme_image_path",
1653 themeDisplayElement.elementText("path-theme-images"));
1654
1655 _populateCustomTokens(tokens);
1656
1657
1658
1659 tokens.put(
1660 "friendly_url",
1661 themeDisplayElement.elementText("path-friendly-url-public"));
1662 tokens.put(
1663 "friendly_url_private",
1664 themeDisplayElement.elementText("path-friendly-url-private-group"));
1665 tokens.put("group_id", String.valueOf(articleGroupId));
1666 tokens.put(
1667 "page_url",
1668 themeDisplayElement.elementText("path-friendly-url-public"));
1669 }
1670
1671 private static void _populateTokens(
1672 Map<String, String> tokens, long articleGroupId,
1673 ThemeDisplay themeDisplay)
1674 throws PortalException, SystemException {
1675
1676 Layout layout = themeDisplay.getLayout();
1677
1678 Group group = layout.getGroup();
1679
1680 LayoutSet layoutSet = layout.getLayoutSet();
1681
1682 String friendlyUrlCurrent = null;
1683
1684 if (layout.isPublicLayout()) {
1685 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPublic();
1686 }
1687 else if (group.isUserGroup()) {
1688 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateUser();
1689 }
1690 else {
1691 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateGroup();
1692 }
1693
1694 String layoutSetFriendlyUrl = themeDisplay.getI18nPath();
1695
1696 String virtualHostname = layoutSet.getVirtualHostname();
1697
1698 if (Validator.isNull(virtualHostname) ||
1699 !virtualHostname.equals(themeDisplay.getServerName())) {
1700
1701 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1702 }
1703
1704 tokens.put("article_group_id", String.valueOf(articleGroupId));
1705 tokens.put("cdn_host", themeDisplay.getCDNHost());
1706 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
1707 tokens.put("friendly_url_current", friendlyUrlCurrent);
1708 tokens.put(
1709 "friendly_url_private_group",
1710 themeDisplay.getPathFriendlyURLPrivateGroup());
1711 tokens.put(
1712 "friendly_url_private_user",
1713 themeDisplay.getPathFriendlyURLPrivateUser());
1714 tokens.put(
1715 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
1716 tokens.put("group_friendly_url", group.getFriendlyURL());
1717 tokens.put("image_path", themeDisplay.getPathImage());
1718 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1719 tokens.put("main_path", themeDisplay.getPathMain());
1720 tokens.put("portal_ctx", themeDisplay.getPathContext());
1721 tokens.put(
1722 "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
1723 tokens.put(
1724 "protocol", HttpUtil.getProtocol(themeDisplay.getURLPortal()));
1725 tokens.put("root_path", themeDisplay.getPathContext());
1726 tokens.put(
1727 "site_group_id", String.valueOf(themeDisplay.getSiteGroupId()));
1728 tokens.put(
1729 "scope_group_id", String.valueOf(themeDisplay.getScopeGroupId()));
1730 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
1731
1732 _populateCustomTokens(tokens);
1733
1734
1735
1736 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
1737 tokens.put(
1738 "friendly_url_private",
1739 themeDisplay.getPathFriendlyURLPrivateGroup());
1740 tokens.put("group_id", String.valueOf(articleGroupId));
1741 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
1742 }
1743
1744 private static void _removeOldContent(
1745 Stack<String> path, Element contentElement, Document xsdDocument)
1746 throws SystemException {
1747
1748 String elementPath = "";
1749
1750 for (int i = 0; i < path.size(); i++) {
1751 elementPath += "/" + path.elementAt(i);
1752 }
1753
1754 for (int i = 0; i < contentElement.nodeCount(); i++) {
1755 Node contentNode = contentElement.node(i);
1756
1757 if (contentNode instanceof Element) {
1758 _removeOldContent(
1759 path, (Element)contentNode, xsdDocument, elementPath);
1760 }
1761 }
1762 }
1763
1764 private static void _removeOldContent(
1765 Stack<String> path, Element contentElement, Document xsdDocument,
1766 String elementPath)
1767 throws SystemException {
1768
1769 String name = contentElement.attributeValue("name");
1770
1771 if (Validator.isNull(name)) {
1772 return;
1773 }
1774
1775 String localPath =
1776 "dynamic-element[@name=" + HtmlUtil.escapeXPathAttribute(name) +
1777 "]";
1778
1779 String fullPath = elementPath + "/" + localPath;
1780
1781 XPath xPathSelector = SAXReaderUtil.createXPath(fullPath);
1782
1783 List<Node> curNodes = xPathSelector.selectNodes(xsdDocument);
1784
1785 if (curNodes.size() == 0) {
1786 contentElement.detach();
1787 }
1788
1789 path.push(localPath);
1790
1791 _removeOldContent(path, contentElement, xsdDocument);
1792
1793 path.pop();
1794 }
1795
1796 private static Log _log = LogFactoryUtil.getLog(JournalUtil.class);
1797
1798 private static Map<String, String> _customTokens;
1799 private static Pattern _friendlyURLPattern = Pattern.compile("[^a-z0-9_-]");
1800 private static Transformer _transformer = new Transformer(
1801 PropsKeys.JOURNAL_TRANSFORMER_LISTENER,
1802 PropsKeys.JOURNAL_ERROR_TEMPLATE, true);
1803
1804 }