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.Transformer;
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.theme.ThemeDisplay;
061 import com.liferay.portal.util.PortalUtil;
062 import com.liferay.portal.util.PortletKeys;
063 import com.liferay.portal.util.PropsUtil;
064 import com.liferay.portal.util.PropsValues;
065 import com.liferay.portal.util.WebKeys;
066 import com.liferay.portal.webserver.WebServerServletTokenUtil;
067 import com.liferay.portlet.PortletURLFactoryUtil;
068 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
069 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
070 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
071 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
072 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
073 import com.liferay.portlet.journal.NoSuchArticleException;
074 import com.liferay.portlet.journal.StructureXsdException;
075 import com.liferay.portlet.journal.model.JournalArticle;
076 import com.liferay.portlet.journal.model.JournalFolder;
077 import com.liferay.portlet.journal.model.JournalFolderConstants;
078 import com.liferay.portlet.journal.model.JournalStructureConstants;
079 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
080 import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
081 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
082 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
083 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
084 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
085 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
086 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
087 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
088 import com.liferay.util.ContentUtil;
089 import com.liferay.util.FiniteUniqueStack;
090
091 import java.util.ArrayList;
092 import java.util.Collections;
093 import java.util.Date;
094 import java.util.HashMap;
095 import java.util.Iterator;
096 import java.util.List;
097 import java.util.Map;
098 import java.util.Stack;
099
100 import javax.portlet.PortletPreferences;
101 import javax.portlet.PortletRequest;
102 import javax.portlet.PortletSession;
103 import javax.portlet.PortletURL;
104 import javax.portlet.RenderResponse;
105
106 import javax.servlet.http.HttpServletRequest;
107
108
115 public class JournalUtil {
116
117 public static final int MAX_STACK_SIZE = 20;
118
119 public static void addAllReservedEls(
120 Element rootElement, Map<String, String> tokens, JournalArticle article,
121 String languageId, ThemeDisplay themeDisplay) {
122
123 JournalUtil.addReservedEl(
124 rootElement, tokens, JournalStructureConstants.RESERVED_ARTICLE_ID,
125 article.getArticleId());
126
127 JournalUtil.addReservedEl(
128 rootElement, tokens,
129 JournalStructureConstants.RESERVED_ARTICLE_VERSION,
130 article.getVersion());
131
132 JournalUtil.addReservedEl(
133 rootElement, tokens,
134 JournalStructureConstants.RESERVED_ARTICLE_TITLE,
135 article.getTitle(languageId));
136
137 JournalUtil.addReservedEl(
138 rootElement, tokens,
139 JournalStructureConstants.RESERVED_ARTICLE_URL_TITLE,
140 article.getUrlTitle());
141
142 JournalUtil.addReservedEl(
143 rootElement, tokens,
144 JournalStructureConstants.RESERVED_ARTICLE_DESCRIPTION,
145 article.getDescription(languageId));
146
147 JournalUtil.addReservedEl(
148 rootElement, tokens,
149 JournalStructureConstants.RESERVED_ARTICLE_TYPE, article.getType());
150
151 JournalUtil.addReservedEl(
152 rootElement, tokens,
153 JournalStructureConstants.RESERVED_ARTICLE_CREATE_DATE,
154 article.getCreateDate());
155
156 JournalUtil.addReservedEl(
157 rootElement, tokens,
158 JournalStructureConstants.RESERVED_ARTICLE_MODIFIED_DATE,
159 article.getModifiedDate());
160
161 if (article.getDisplayDate() != null) {
162 JournalUtil.addReservedEl(
163 rootElement, tokens,
164 JournalStructureConstants.RESERVED_ARTICLE_DISPLAY_DATE,
165 article.getDisplayDate());
166 }
167
168 String smallImageURL = StringPool.BLANK;
169
170 if (Validator.isNotNull(article.getSmallImageURL())) {
171 smallImageURL = article.getSmallImageURL();
172 }
173 else if ((themeDisplay != null) && article.isSmallImage()) {
174 StringBundler sb = new StringBundler(5);
175
176 sb.append(themeDisplay.getPathImage());
177 sb.append("/journal/article?img_id=");
178 sb.append(article.getSmallImageId());
179 sb.append("&t=");
180 sb.append(
181 WebServerServletTokenUtil.getToken(article.getSmallImageId()));
182
183 smallImageURL = sb.toString();
184 }
185
186 JournalUtil.addReservedEl(
187 rootElement, tokens,
188 JournalStructureConstants.RESERVED_ARTICLE_SMALL_IMAGE_URL,
189 smallImageURL);
190
191 String[] assetTagNames = new String[0];
192
193 try {
194 assetTagNames = AssetTagLocalServiceUtil.getTagNames(
195 JournalArticle.class.getName(), article.getResourcePrimKey());
196 }
197 catch (SystemException se) {
198 }
199
200 JournalUtil.addReservedEl(
201 rootElement, tokens,
202 JournalStructureConstants.RESERVED_ARTICLE_ASSET_TAG_NAMES,
203 StringUtil.merge(assetTagNames));
204
205 JournalUtil.addReservedEl(
206 rootElement, tokens,
207 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_ID,
208 String.valueOf(article.getUserId()));
209
210 String userName = StringPool.BLANK;
211 String userEmailAddress = StringPool.BLANK;
212 String userComments = StringPool.BLANK;
213 String userJobTitle = StringPool.BLANK;
214
215 User user = null;
216
217 try {
218 user = UserLocalServiceUtil.getUserById(article.getUserId());
219
220 userName = user.getFullName();
221 userEmailAddress = user.getEmailAddress();
222 userComments = user.getComments();
223 userJobTitle = user.getJobTitle();
224 }
225 catch (PortalException pe) {
226 }
227 catch (SystemException se) {
228 }
229
230 JournalUtil.addReservedEl(
231 rootElement, tokens,
232 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_NAME, userName);
233
234 JournalUtil.addReservedEl(
235 rootElement, tokens,
236 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_EMAIL_ADDRESS,
237 userEmailAddress);
238
239 JournalUtil.addReservedEl(
240 rootElement, tokens,
241 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_COMMENTS,
242 userComments);
243
244 JournalUtil.addReservedEl(
245 rootElement, tokens,
246 JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_JOB_TITLE,
247 userJobTitle);
248 }
249
250 public static void addPortletBreadcrumbEntries(
251 JournalArticle article, HttpServletRequest request,
252 RenderResponse renderResponse)
253 throws Exception {
254
255 JournalFolder folder = article.getFolder();
256
257 if (folder.getFolderId() !=
258 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
259
260 addPortletBreadcrumbEntries(folder, request, renderResponse);
261 }
262
263 JournalArticle unescapedArticle = article.toUnescapedModel();
264
265 PortletURL portletURL = renderResponse.createRenderURL();
266
267 portletURL.setParameter("struts_action", "/article/view_article");
268 portletURL.setParameter(
269 "groupId", String.valueOf(article.getGroupId()));
270 portletURL.setParameter(
271 "articleId", String.valueOf(article.getArticleId()));
272
273 PortalUtil.addPortletBreadcrumbEntry(
274 request, unescapedArticle.getTitle(), portletURL.toString());
275 }
276
277 public static void addPortletBreadcrumbEntries(
278 JournalFolder folder, HttpServletRequest request,
279 LiferayPortletResponse liferayPortletResponse)
280 throws Exception {
281
282 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
283 com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
284
285 String strutsAction = ParamUtil.getString(request, "struts_action");
286
287 PortletURL portletURL = liferayPortletResponse.createRenderURL();
288
289 if (strutsAction.equals("/journal/select_folder")) {
290 portletURL.setWindowState(LiferayWindowState.POP_UP);
291
292 portletURL.setParameter("struts_action", "/journal/select_folder");
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 templateId, Map<String, String> tokens,
984 String languageId)
985 throws PortalException, SystemException {
986
987 return getTemplateScript(groupId, templateId, tokens, languageId, true);
988 }
989
990 public static String getTemplateScript(
991 long groupId, String templateId, Map<String, String> tokens,
992 String languageId, boolean transform)
993 throws PortalException, SystemException {
994
995 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
996 groupId, PortalUtil.getClassNameId(DDMStructure.class), templateId);
997
998 return getTemplateScript(ddmTemplate, tokens, languageId, transform);
999 }
1000
1001 public static Map<String, String> getTokens(
1002 long groupId, ThemeDisplay themeDisplay)
1003 throws PortalException, SystemException {
1004
1005 return getTokens(groupId, themeDisplay, null);
1006 }
1007
1008 public static Map<String, String> getTokens(
1009 long groupId, ThemeDisplay themeDisplay, String xmlRequest)
1010 throws PortalException, SystemException {
1011
1012 Map<String, String> tokens = new HashMap<String, String>();
1013
1014 if (themeDisplay != null) {
1015 _populateTokens(tokens, groupId, themeDisplay);
1016 }
1017 else if (Validator.isNotNull(xmlRequest)) {
1018 try {
1019 _populateTokens(tokens, groupId, xmlRequest);
1020 }
1021 catch (Exception e) {
1022 if (_log.isWarnEnabled()) {
1023 _log.warn(e, e);
1024 }
1025 }
1026 }
1027
1028 return tokens;
1029 }
1030
1031 public static String getUrlTitle(long id, String title) {
1032 if (title == null) {
1033 return String.valueOf(id);
1034 }
1035
1036 title = title.trim().toLowerCase();
1037
1038 if (Validator.isNull(title) || Validator.isNumber(title) ||
1039 title.equals("rss")) {
1040
1041 title = String.valueOf(id);
1042 }
1043 else {
1044 title = FriendlyURLNormalizerUtil.normalize(
1045 title, _URL_TITLE_REPLACE_CHARS);
1046 }
1047
1048 return ModelHintsUtil.trimString(
1049 JournalArticle.class.getName(), "urlTitle", title);
1050 }
1051
1052 public static String mergeArticleContent(
1053 String curContent, String newContent, boolean removeNullElements) {
1054
1055 try {
1056 Document curDocument = SAXReaderUtil.read(curContent);
1057 Document newDocument = SAXReaderUtil.read(newContent);
1058
1059 Element curRootElement = curDocument.getRootElement();
1060 Element newRootElement = newDocument.getRootElement();
1061
1062 curRootElement.addAttribute(
1063 "default-locale",
1064 newRootElement.attributeValue("default-locale"));
1065 curRootElement.addAttribute(
1066 "available-locales",
1067 newRootElement.attributeValue("available-locales"));
1068
1069 _mergeArticleContentUpdate(
1070 curDocument, newRootElement,
1071 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
1072
1073 if (removeNullElements) {
1074 _mergeArticleContentDelete(curRootElement, newDocument);
1075 }
1076
1077 curContent = DDMXMLUtil.formatXML(curDocument);
1078 }
1079 catch (Exception e) {
1080 _log.error(e, e);
1081 }
1082
1083 return curContent;
1084 }
1085
1086 public static void removeArticleLocale(Element element, String languageId)
1087 throws PortalException, SystemException {
1088
1089 for (Element dynamicElementElement :
1090 element.elements("dynamic-element")) {
1091
1092 for (Element dynamicContentElement :
1093 dynamicElementElement.elements("dynamic-content")) {
1094
1095 String curLanguageId = GetterUtil.getString(
1096 dynamicContentElement.attributeValue("language-id"));
1097
1098 if (curLanguageId.equals(languageId)) {
1099 long id = GetterUtil.getLong(
1100 dynamicContentElement.attributeValue("id"));
1101
1102 if (id > 0) {
1103 ImageLocalServiceUtil.deleteImage(id);
1104 }
1105
1106 dynamicContentElement.detach();
1107 }
1108 }
1109
1110 removeArticleLocale(dynamicElementElement, languageId);
1111 }
1112 }
1113
1114 public static String removeArticleLocale(
1115 String content, String languageId) {
1116
1117 try {
1118 Document document = SAXReaderUtil.read(content);
1119
1120 Element rootElement = document.getRootElement();
1121
1122 String availableLocales = rootElement.attributeValue(
1123 "available-locales");
1124
1125 if (availableLocales == null) {
1126 return content;
1127 }
1128
1129 availableLocales = StringUtil.remove(availableLocales, languageId);
1130
1131 if (availableLocales.endsWith(",")) {
1132 availableLocales = availableLocales.substring(
1133 0, availableLocales.length() - 1);
1134 }
1135
1136 rootElement.addAttribute("available-locales", availableLocales);
1137
1138 removeArticleLocale(rootElement, languageId);
1139
1140 content = DDMXMLUtil.formatXML(document);
1141 }
1142 catch (Exception e) {
1143 _log.error(e, e);
1144 }
1145
1146 return content;
1147 }
1148
1149 public static String removeOldContent(String content, String xsd) {
1150 try {
1151 Document contentDoc = SAXReaderUtil.read(content);
1152 Document xsdDoc = SAXReaderUtil.read(xsd);
1153
1154 Element contentRoot = contentDoc.getRootElement();
1155
1156 Stack<String> path = new Stack<String>();
1157
1158 path.push(contentRoot.getName());
1159
1160 _removeOldContent(path, contentRoot, xsdDoc);
1161
1162 content = DDMXMLUtil.formatXML(contentDoc);
1163 }
1164 catch (Exception e) {
1165 _log.error(e, e);
1166 }
1167
1168 return content;
1169 }
1170
1171 public static void removeRecentArticle(
1172 PortletRequest portletRequest, String articleId) {
1173
1174 removeRecentArticle(portletRequest, articleId, 0);
1175 }
1176
1177 public static void removeRecentArticle(
1178 PortletRequest portletRequest, String articleId, double version) {
1179
1180 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
1181
1182 Iterator<JournalArticle> itr = stack.iterator();
1183
1184 while (itr.hasNext()) {
1185 JournalArticle journalArticle = itr.next();
1186
1187 if (journalArticle.getArticleId().equals(articleId) &&
1188 ((journalArticle.getVersion() == version) ||
1189 (version == 0))) {
1190
1191 itr.remove();
1192 }
1193 }
1194 }
1195
1196 public static void removeRecentDDMStructure(
1197 PortletRequest portletRequest, String structureId) {
1198
1199 Stack<DDMStructure> stack = getRecentDDMStructures(portletRequest);
1200
1201 Iterator<DDMStructure> itr = stack.iterator();
1202
1203 while (itr.hasNext()) {
1204 DDMStructure ddmStructure = itr.next();
1205
1206 if (structureId.equals(ddmStructure.getStructureKey())) {
1207 itr.remove();
1208
1209 break;
1210 }
1211 }
1212 }
1213
1214 public static void removeRecentDDMTemplate(
1215 PortletRequest portletRequest, String templateId) {
1216
1217 Stack<DDMTemplate> stack = getRecentDDMTemplates(portletRequest);
1218
1219 Iterator<DDMTemplate> itr = stack.iterator();
1220
1221 while (itr.hasNext()) {
1222 DDMTemplate ddmTemplate = itr.next();
1223
1224 if (templateId.equals(ddmTemplate.getTemplateKey())) {
1225 itr.remove();
1226
1227 break;
1228 }
1229 }
1230 }
1231
1232 public static String transform(
1233 ThemeDisplay themeDisplay, Map<String, String> tokens,
1234 String viewMode, String languageId, String xml, String script,
1235 String langType)
1236 throws Exception {
1237
1238 return _transformer.transform(
1239 themeDisplay, tokens, viewMode, languageId, xml, script, langType);
1240 }
1241
1242 public static String validateXSD(String xsd) throws PortalException {
1243 try {
1244 Document document = SAXReaderUtil.read(xsd);
1245
1246 return document.asXML();
1247 }
1248 catch (Exception e) {
1249 throw new StructureXsdException();
1250 }
1251 }
1252
1253 private static void _addElementOptions(
1254 Element curContentElement, Element newContentElement) {
1255
1256 List<Element> newElementOptions = newContentElement.elements("option");
1257
1258 for (Element newElementOption : newElementOptions) {
1259 Element curElementOption = SAXReaderUtil.createElement("option");
1260
1261 curElementOption.addCDATA(newElementOption.getText());
1262
1263 curContentElement.add(curElementOption);
1264 }
1265 }
1266
1267 private static Element _getElementByInstanceId(
1268 Document document, String instanceId) {
1269
1270 XPath xPathSelector = SAXReaderUtil.createXPath(
1271 "
1272 HtmlUtil.escapeXPathAttribute(instanceId) + "]");
1273
1274 List<Node> nodes = xPathSelector.selectNodes(document);
1275
1276 if (nodes.size() == 1) {
1277 return (Element)nodes.get(0);
1278 }
1279 else {
1280 return null;
1281 }
1282 }
1283
1284 private static void _mergeArticleContentDelete(
1285 Element curParentElement, Document newDocument)
1286 throws Exception {
1287
1288 List<Element> curElements = curParentElement.elements(
1289 "dynamic-element");
1290
1291 for (int i = 0; i < curElements.size(); i++) {
1292 Element curElement = curElements.get(i);
1293
1294 _mergeArticleContentDelete(curElement, newDocument);
1295
1296 String instanceId = curElement.attributeValue("instance-id");
1297
1298 Element newElement = _getElementByInstanceId(
1299 newDocument, instanceId);
1300
1301 if (newElement == null) {
1302 curElement.detach();
1303 }
1304 }
1305 }
1306
1307 private static void _mergeArticleContentUpdate(
1308 Document curDocument, Element newParentElement, Element newElement,
1309 int pos, String defaultLocale)
1310 throws Exception {
1311
1312 _mergeArticleContentUpdate(curDocument, newElement, defaultLocale);
1313
1314 String instanceId = newElement.attributeValue("instance-id");
1315
1316 Element curElement = _getElementByInstanceId(curDocument, instanceId);
1317
1318 if (curElement != null) {
1319 _mergeArticleContentUpdate(curElement, newElement, defaultLocale);
1320 }
1321 else {
1322 String parentInstanceId = newParentElement.attributeValue(
1323 "instance-id");
1324
1325 if (Validator.isNull(parentInstanceId)) {
1326 Element curRoot = curDocument.getRootElement();
1327
1328 List<Element> curRootElements = curRoot.elements();
1329
1330 curRootElements.add(pos, newElement.createCopy());
1331 }
1332 else {
1333 Element curParentElement = _getElementByInstanceId(
1334 curDocument, parentInstanceId);
1335
1336 if (curParentElement != null) {
1337 List<Element> curParentElements =
1338 curParentElement.elements();
1339
1340 curParentElements.add(pos, newElement.createCopy());
1341 }
1342 }
1343 }
1344 }
1345
1346 private static void _mergeArticleContentUpdate(
1347 Document curDocument, Element newParentElement,
1348 String defaultLocale)
1349 throws Exception {
1350
1351 List<Element> newElements = newParentElement.elements(
1352 "dynamic-element");
1353
1354 for (int i = 0; i < newElements.size(); i++) {
1355 Element newElement = newElements.get(i);
1356
1357 _mergeArticleContentUpdate(
1358 curDocument, newParentElement, newElement, i, defaultLocale);
1359 }
1360 }
1361
1362 private static void _mergeArticleContentUpdate(
1363 Element curElement, Element newElement, String defaultLocale) {
1364
1365 Attribute curTypeAttribute = curElement.attribute("type");
1366 Attribute newTypeAttribute = newElement.attribute("type");
1367
1368 curTypeAttribute.setValue(newTypeAttribute.getValue());
1369
1370 Attribute curIndexTypeAttribute = curElement.attribute("index-type");
1371 Attribute newIndexTypeAttribute = newElement.attribute("index-type");
1372
1373 if (newIndexTypeAttribute != null) {
1374 if (curIndexTypeAttribute == null) {
1375 curElement.addAttribute(
1376 "index-type", newIndexTypeAttribute.getValue());
1377 } else {
1378 curIndexTypeAttribute.setValue(
1379 newIndexTypeAttribute.getValue());
1380 }
1381 }
1382
1383 Element newContentElement = newElement.elements(
1384 "dynamic-content").get(0);
1385
1386 String newLanguageId = newContentElement.attributeValue("language-id");
1387 String newValue = newContentElement.getText();
1388
1389 String indexType = newElement.attributeValue("index-type");
1390
1391 if (Validator.isNotNull(indexType)) {
1392 curElement.addAttribute("index-type", indexType);
1393 }
1394
1395 List<Element> curContentElements = curElement.elements(
1396 "dynamic-content");
1397
1398 if (Validator.isNull(newLanguageId)) {
1399 for (Element curContentElement : curContentElements) {
1400 curContentElement.detach();
1401 }
1402
1403 Element curContentElement = SAXReaderUtil.createElement(
1404 "dynamic-content");
1405
1406 if (newContentElement.element("option") != null) {
1407 _addElementOptions(curContentElement, newContentElement);
1408 }
1409 else {
1410 curContentElement.addCDATA(newValue);
1411 }
1412
1413 curElement.add(curContentElement);
1414 }
1415 else {
1416 boolean alreadyExists = false;
1417
1418 for (Element curContentElement : curContentElements) {
1419 String curLanguageId = curContentElement.attributeValue(
1420 "language-id");
1421
1422 if (newLanguageId.equals(curLanguageId)) {
1423 alreadyExists = true;
1424
1425 curContentElement.clearContent();
1426
1427 if (newContentElement.element("option") != null) {
1428 _addElementOptions(
1429 curContentElement, newContentElement);
1430 }
1431 else {
1432 curContentElement.addCDATA(newValue);
1433 }
1434
1435 break;
1436 }
1437 }
1438
1439 if (!alreadyExists) {
1440 Element curContentElement = curContentElements.get(0);
1441
1442 String curLanguageId = curContentElement.attributeValue(
1443 "language-id");
1444
1445 if (Validator.isNull(curLanguageId)) {
1446 if (newLanguageId.equals(defaultLocale)) {
1447 curContentElement.clearContent();
1448
1449 if (newContentElement.element("option") != null) {
1450 _addElementOptions(
1451 curContentElement, newContentElement);
1452 }
1453 else {
1454 curContentElement.addCDATA(newValue);
1455 }
1456 }
1457 else {
1458 curElement.add(newContentElement.createCopy());
1459 }
1460
1461 curContentElement.addAttribute(
1462 "language-id", defaultLocale);
1463 }
1464 else {
1465 curElement.add(newContentElement.createCopy());
1466 }
1467 }
1468 }
1469 }
1470
1471 private static void _populateCustomTokens(Map<String, String> tokens) {
1472 if (_customTokens == null) {
1473 synchronized (JournalUtil.class) {
1474 _customTokens = new HashMap<String, String>();
1475
1476 for (String customToken :
1477 PropsValues.JOURNAL_ARTICLE_CUSTOM_TOKENS) {
1478
1479 String value = PropsUtil.get(
1480 PropsKeys.JOURNAL_ARTICLE_CUSTOM_TOKEN_VALUE,
1481 new Filter(customToken));
1482
1483 _customTokens.put(customToken, value);
1484 }
1485 }
1486 }
1487
1488 if (!_customTokens.isEmpty()) {
1489 tokens.putAll(_customTokens);
1490 }
1491 }
1492
1493 private static void _populateTokens(
1494 Map<String, String> tokens, long groupId, String xmlRequest)
1495 throws Exception {
1496
1497 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1498
1499 Element rootElement = requestDocument.getRootElement();
1500
1501 Element themeDisplayElement = rootElement.element("theme-display");
1502
1503 Layout layout = LayoutLocalServiceUtil.getLayout(
1504 GetterUtil.getLong(themeDisplayElement.elementText("plid")));
1505
1506 Group group = layout.getGroup();
1507
1508 LayoutSet layoutSet = layout.getLayoutSet();
1509
1510 String friendlyUrlCurrent = null;
1511
1512 if (layout.isPublicLayout()) {
1513 friendlyUrlCurrent = themeDisplayElement.elementText(
1514 "path-friendly-url-public");
1515 }
1516 else if (group.isUserGroup()) {
1517 friendlyUrlCurrent = themeDisplayElement.elementText(
1518 "path-friendly-url-private-user");
1519 }
1520 else {
1521 friendlyUrlCurrent = themeDisplayElement.elementText(
1522 "path-friendly-url-private-group");
1523 }
1524
1525 String layoutSetFriendlyUrl = themeDisplayElement.elementText(
1526 "i18n-path");
1527
1528 String virtualHostname = layoutSet.getVirtualHostname();
1529
1530 if (Validator.isNull(virtualHostname) ||
1531 !virtualHostname.equals(
1532 themeDisplayElement.elementText("server-name"))) {
1533
1534 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1535 }
1536
1537 tokens.put("cdn_host", themeDisplayElement.elementText("cdn-host"));
1538 tokens.put("company_id", themeDisplayElement.elementText("company-id"));
1539 tokens.put("friendly_url_current", friendlyUrlCurrent);
1540 tokens.put(
1541 "friendly_url_private_group",
1542 themeDisplayElement.elementText("path-friendly-url-private-group"));
1543 tokens.put(
1544 "friendly_url_private_user",
1545 themeDisplayElement.elementText("path-friendly-url-private-user"));
1546 tokens.put(
1547 "friendly_url_public",
1548 themeDisplayElement.elementText("path-friendly-url-public"));
1549 tokens.put("group_friendly_url", group.getFriendlyURL());
1550 tokens.put("group_id", String.valueOf(groupId));
1551 tokens.put("image_path", themeDisplayElement.elementText("path-image"));
1552 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1553 tokens.put("main_path", themeDisplayElement.elementText("path-main"));
1554 tokens.put(
1555 "portal_ctx", themeDisplayElement.elementText("path-context"));
1556 tokens.put(
1557 "portal_url",
1558 HttpUtil.removeProtocol(
1559 themeDisplayElement.elementText("url-portal")));
1560 tokens.put(
1561 "protocol",
1562 HttpUtil.getProtocol(
1563 themeDisplayElement.elementText("url-portal")));
1564 tokens.put(
1565 "root_path", themeDisplayElement.elementText("path-context"));
1566 tokens.put(
1567 "theme_image_path",
1568 themeDisplayElement.elementText("path-theme-images"));
1569
1570 _populateCustomTokens(tokens);
1571
1572
1573
1574 tokens.put(
1575 "friendly_url",
1576 themeDisplayElement.elementText("path-friendly-url-public"));
1577 tokens.put(
1578 "friendly_url_private",
1579 themeDisplayElement.elementText("path-friendly-url-private-group"));
1580 tokens.put(
1581 "page_url",
1582 themeDisplayElement.elementText("path-friendly-url-public"));
1583 }
1584
1585 private static void _populateTokens(
1586 Map<String, String> tokens, long groupId, ThemeDisplay themeDisplay)
1587 throws PortalException, SystemException {
1588
1589 Layout layout = themeDisplay.getLayout();
1590
1591 Group group = layout.getGroup();
1592
1593 LayoutSet layoutSet = layout.getLayoutSet();
1594
1595 String friendlyUrlCurrent = null;
1596
1597 if (layout.isPublicLayout()) {
1598 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPublic();
1599 }
1600 else if (group.isUserGroup()) {
1601 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateUser();
1602 }
1603 else {
1604 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateGroup();
1605 }
1606
1607 String layoutSetFriendlyUrl = themeDisplay.getI18nPath();
1608
1609 String virtualHostname = layoutSet.getVirtualHostname();
1610
1611 if (Validator.isNull(virtualHostname) ||
1612 !virtualHostname.equals(themeDisplay.getServerName())) {
1613
1614 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1615 }
1616
1617 tokens.put("cdn_host", themeDisplay.getCDNHost());
1618 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
1619 tokens.put("friendly_url_current", friendlyUrlCurrent);
1620 tokens.put(
1621 "friendly_url_private_group",
1622 themeDisplay.getPathFriendlyURLPrivateGroup());
1623 tokens.put(
1624 "friendly_url_private_user",
1625 themeDisplay.getPathFriendlyURLPrivateUser());
1626 tokens.put(
1627 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
1628 tokens.put("group_friendly_url", group.getFriendlyURL());
1629 tokens.put("group_id", String.valueOf(groupId));
1630 tokens.put("image_path", themeDisplay.getPathImage());
1631 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1632 tokens.put("main_path", themeDisplay.getPathMain());
1633 tokens.put("portal_ctx", themeDisplay.getPathContext());
1634 tokens.put(
1635 "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
1636 tokens.put(
1637 "protocol", HttpUtil.getProtocol(themeDisplay.getURLPortal()));
1638 tokens.put("root_path", themeDisplay.getPathContext());
1639 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
1640
1641 _populateCustomTokens(tokens);
1642
1643
1644
1645 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
1646 tokens.put(
1647 "friendly_url_private",
1648 themeDisplay.getPathFriendlyURLPrivateGroup());
1649 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
1650 }
1651
1652 private static void _removeOldContent(
1653 Stack<String> path, Element contentElement, Document xsdDocument)
1654 throws SystemException {
1655
1656 String elementPath = "";
1657
1658 for (int i = 0; i < path.size(); i++) {
1659 elementPath += "/" + path.elementAt(i);
1660 }
1661
1662 for (int i = 0; i < contentElement.nodeCount(); i++) {
1663 Node contentNode = contentElement.node(i);
1664
1665 if (contentNode instanceof Element) {
1666 _removeOldContent(
1667 path, (Element)contentNode, xsdDocument, elementPath);
1668 }
1669 }
1670 }
1671
1672 private static void _removeOldContent(
1673 Stack<String> path, Element contentElement, Document xsdDocument,
1674 String elementPath)
1675 throws SystemException {
1676
1677 String name = contentElement.attributeValue("name");
1678
1679 if (Validator.isNull(name)) {
1680 return;
1681 }
1682
1683 String localPath =
1684 "dynamic-element[@name=" + HtmlUtil.escapeXPathAttribute(name) +
1685 "]";
1686
1687 String fullPath = elementPath + "/" + localPath;
1688
1689 XPath xPathSelector = SAXReaderUtil.createXPath(fullPath);
1690
1691 List<Node> curNodes = xPathSelector.selectNodes(xsdDocument);
1692
1693 if (curNodes.size() == 0) {
1694 contentElement.detach();
1695 }
1696
1697 path.push(localPath);
1698
1699 _removeOldContent(path, contentElement, xsdDocument);
1700
1701 path.pop();
1702 }
1703
1704 private static final char[] _URL_TITLE_REPLACE_CHARS = new char[] {
1705 '.', '/'
1706 };
1707
1708 private static Log _log = LogFactoryUtil.getLog(JournalUtil.class);
1709
1710 private static Map<String, String> _customTokens;
1711 private static Transformer _transformer = new JournalTransformer();
1712
1713 }