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