1
22
23 package com.liferay.portlet.journal.util;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.configuration.Filter;
28 import com.liferay.portal.kernel.log.Log;
29 import com.liferay.portal.kernel.log.LogFactoryUtil;
30 import com.liferay.portal.kernel.util.Constants;
31 import com.liferay.portal.kernel.util.GetterUtil;
32 import com.liferay.portal.kernel.util.HttpUtil;
33 import com.liferay.portal.kernel.util.InstancePool;
34 import com.liferay.portal.kernel.util.LocaleUtil;
35 import com.liferay.portal.kernel.util.OrderByComparator;
36 import com.liferay.portal.kernel.util.PropertiesUtil;
37 import com.liferay.portal.kernel.util.PropsKeys;
38 import com.liferay.portal.kernel.util.StringPool;
39 import com.liferay.portal.kernel.util.StringUtil;
40 import com.liferay.portal.kernel.util.Time;
41 import com.liferay.portal.kernel.util.Validator;
42 import com.liferay.portal.kernel.xml.Document;
43 import com.liferay.portal.kernel.xml.Element;
44 import com.liferay.portal.kernel.xml.Node;
45 import com.liferay.portal.kernel.xml.SAXReaderUtil;
46 import com.liferay.portal.kernel.xml.XPath;
47 import com.liferay.portal.model.Group;
48 import com.liferay.portal.model.Layout;
49 import com.liferay.portal.model.LayoutSet;
50 import com.liferay.portal.model.User;
51 import com.liferay.portal.service.ImageLocalServiceUtil;
52 import com.liferay.portal.service.LayoutLocalServiceUtil;
53 import com.liferay.portal.service.UserLocalServiceUtil;
54 import com.liferay.portal.theme.ThemeDisplay;
55 import com.liferay.portal.util.ContentUtil;
56 import com.liferay.portal.util.FriendlyURLNormalizer;
57 import com.liferay.portal.util.PropsUtil;
58 import com.liferay.portal.util.WebKeys;
59 import com.liferay.portlet.journal.TransformException;
60 import com.liferay.portlet.journal.model.JournalArticle;
61 import com.liferay.portlet.journal.model.JournalStructure;
62 import com.liferay.portlet.journal.model.JournalTemplate;
63 import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
64 import com.liferay.portlet.journal.service.JournalArticleImageLocalServiceUtil;
65 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
66 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
67 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
68 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
69 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
70 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
71 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
72 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
73 import com.liferay.portlet.tags.service.TagsEntryLocalServiceUtil;
74 import com.liferay.util.FiniteUniqueStack;
75 import com.liferay.util.LocalizationUtil;
76 import com.liferay.util.xml.XMLFormatter;
77
78 import java.io.IOException;
79
80 import java.util.ArrayList;
81 import java.util.Date;
82 import java.util.HashMap;
83 import java.util.Iterator;
84 import java.util.List;
85 import java.util.Map;
86 import java.util.Stack;
87
88 import javax.portlet.PortletPreferences;
89 import javax.portlet.PortletRequest;
90 import javax.portlet.PortletSession;
91
92
99 public class JournalUtil {
100
101 public static final int MAX_STACK_SIZE = 20;
102
103 public static final String XML_INDENT = " ";
104
105 public static void addRecentArticle(
106 PortletRequest portletRequest, JournalArticle article) {
107
108 if (article != null) {
109 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
110
111 stack.push(article);
112 }
113 }
114
115 public static void addRecentStructure(
116 PortletRequest portletRequest, JournalStructure structure) {
117
118 if (structure != null) {
119 Stack<JournalStructure> stack = getRecentStructures(portletRequest);
120
121 stack.push(structure);
122 }
123 }
124
125 public static void addRecentTemplate(
126 PortletRequest portletRequest, JournalTemplate template) {
127
128 if (template != null) {
129 Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
130
131 stack.push(template);
132 }
133 }
134
135 public static void addReservedEl(
136 Element root, Map<String, String> tokens, String name, double value) {
137
138 addReservedEl(root, tokens, name, String.valueOf(value));
139 }
140
141 public static void addReservedEl(
142 Element root, Map<String, String> tokens, String name, Date value) {
143
144 addReservedEl(root, tokens, name, Time.getRFC822(value));
145 }
146
147 public static void addReservedEl(
148 Element root, Map<String, String> tokens, String name, String value) {
149
150
152 if (root != null) {
153 Element dynamicEl = SAXReaderUtil.createElement("dynamic-element");
154
155 dynamicEl.add(
156 SAXReaderUtil.createAttribute(dynamicEl, "name", name));
157 dynamicEl.add(
158 SAXReaderUtil.createAttribute(dynamicEl, "type", "text"));
159
160 Element dynamicContent = SAXReaderUtil.createElement(
161 "dynamic-content");
162
163 dynamicContent.setText(value);
165
166 dynamicEl.add(dynamicContent);
167
168 root.add(dynamicEl);
169 }
170
171
173 tokens.put(
174 StringUtil.replace(name, StringPool.DASH, StringPool.UNDERLINE),
175 value);
176 }
177
178 public static void addAllReservedEls(
179 Element root, Map<String, String> tokens, JournalArticle article) {
180
181 JournalUtil.addReservedEl(
182 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_ID,
183 article.getArticleId());
184
185 JournalUtil.addReservedEl(
186 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_VERSION,
187 article.getVersion());
188
189 JournalUtil.addReservedEl(
190 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TITLE,
191 article.getTitle());
192
193 JournalUtil.addReservedEl(
194 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_URL_TITLE,
195 article.getUrlTitle());
196
197 JournalUtil.addReservedEl(
198 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_DESCRIPTION,
199 article.getDescription());
200
201 JournalUtil.addReservedEl(
202 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TYPE,
203 article.getType());
204
205 JournalUtil.addReservedEl(
206 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_CREATE_DATE,
207 article.getCreateDate());
208
209 JournalUtil.addReservedEl(
210 root, tokens,
211 JournalStructureImpl.RESERVED_ARTICLE_MODIFIED_DATE,
212 article.getModifiedDate());
213
214 if (article.getDisplayDate() != null) {
215 JournalUtil.addReservedEl(
216 root, tokens,
217 JournalStructureImpl.RESERVED_ARTICLE_DISPLAY_DATE,
218 article.getDisplayDate());
219 }
220
221 JournalUtil.addReservedEl(
222 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_SMALL_IMAGE_URL,
223 article.getSmallImageURL());
224
225 String[] tagsEntries = new String[0];
226
227 try {
228 tagsEntries = TagsEntryLocalServiceUtil.getEntryNames(
229 JournalArticle.class.getName(), article.getResourcePrimKey());
230 }
231 catch (SystemException se) {
232 }
233
234 JournalUtil.addReservedEl(
235 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_ASSET_TAG_NAMES,
236 StringUtil.merge(tagsEntries));
237
238 JournalUtil.addReservedEl(
239 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_ID,
240 String.valueOf(article.getUserId()));
241
242 String userName = StringPool.BLANK;
243 String userEmailAddress = StringPool.BLANK;
244 String userComments = StringPool.BLANK;
245 String userJobTitle = StringPool.BLANK;
246
247 User user = null;
248
249 try {
250 user = UserLocalServiceUtil.getUserById(article.getUserId());
251
252 userName = user.getFullName();
253 userEmailAddress = user.getEmailAddress();
254 userComments = user.getComments();
255 userJobTitle = user.getJobTitle();
256 }
257 catch (PortalException pe) {
258 }
259 catch (SystemException se) {
260 }
261
262 JournalUtil.addReservedEl(
263 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_NAME,
264 userName);
265
266 JournalUtil.addReservedEl(
267 root, tokens,
268 JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_EMAIL_ADDRESS,
269 userEmailAddress);
270
271 JournalUtil.addReservedEl(
272 root, tokens,
273 JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_COMMENTS,
274 userComments);
275
276 JournalUtil.addReservedEl(
277 root, tokens,
278 JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_JOB_TITLE,
279 userJobTitle);
280 }
281
282 public static String formatVM(String vm) {
283 return vm;
284 }
285
286 public static String formatXML(String xml)
287 throws org.dom4j.DocumentException, IOException {
288
289
293 xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
294
295 xml = XMLFormatter.toString(xml, XML_INDENT);
296
297 xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
298
299 return xml;
300 }
301
302 public static String formatXML(Document doc) throws IOException {
303 return doc.formattedString(XML_INDENT);
304 }
305
306 public static OrderByComparator getArticleOrderByComparator(
307 String orderByCol, String orderByType) {
308
309 boolean orderByAsc = false;
310
311 if (orderByType.equals("asc")) {
312 orderByAsc = true;
313 }
314
315 OrderByComparator orderByComparator = null;
316
317 if (orderByCol.equals("create-date")) {
318 orderByComparator = new ArticleCreateDateComparator(orderByAsc);
319 }
320 else if (orderByCol.equals("display-date")) {
321 orderByComparator = new ArticleDisplayDateComparator(orderByAsc);
322 }
323 else if (orderByCol.equals("id")) {
324 orderByComparator = new ArticleIDComparator(orderByAsc);
325 }
326 else if (orderByCol.equals("modified-date")) {
327 orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
328 }
329 else if (orderByCol.equals("review-date")) {
330 orderByComparator = new ArticleReviewDateComparator(orderByAsc);
331 }
332 else if (orderByCol.equals("title")) {
333 orderByComparator = new ArticleTitleComparator(orderByAsc);
334 }
335 else if (orderByCol.equals("version")) {
336 orderByComparator = new ArticleVersionComparator(orderByAsc);
337 }
338
339 return orderByComparator;
340 }
341
342 public static String getEmailFromAddress(PortletPreferences preferences) {
343 String emailFromAddress = PropsUtil.get(
344 PropsKeys.JOURNAL_EMAIL_FROM_ADDRESS);
345
346 return preferences.getValue("email-from-address", emailFromAddress);
347 }
348
349 public static String getEmailFromName(PortletPreferences preferences) {
350 String emailFromName = PropsUtil.get(
351 PropsKeys.JOURNAL_EMAIL_FROM_NAME);
352
353 return preferences.getValue("email-from-name", emailFromName);
354 }
355
356 public static boolean getEmailArticleApprovalDeniedEnabled(
357 PortletPreferences preferences) {
358
359 String emailArticleApprovalDeniedEnabled = preferences.getValue(
360 "email-article-approval-denied-enabled", StringPool.BLANK);
361
362 if (Validator.isNotNull(emailArticleApprovalDeniedEnabled)) {
363 return GetterUtil.getBoolean(emailArticleApprovalDeniedEnabled);
364 }
365 else {
366 return GetterUtil.getBoolean(PropsUtil.get(
367 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_ENABLED));
368 }
369 }
370
371 public static String getEmailArticleApprovalDeniedBody(
372 PortletPreferences preferences) {
373
374 String emailArticleApprovalDeniedBody = preferences.getValue(
375 "email-article-approval-denied-body", StringPool.BLANK);
376
377 if (Validator.isNotNull(emailArticleApprovalDeniedBody)) {
378 return emailArticleApprovalDeniedBody;
379 }
380 else {
381 return ContentUtil.get(PropsUtil.get(
382 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_BODY));
383 }
384 }
385
386 public static String getEmailArticleApprovalDeniedSubject(
387 PortletPreferences preferences) {
388
389 String emailArticleApprovalDeniedSubject = preferences.getValue(
390 "email-article-approval-denied-subject", StringPool.BLANK);
391
392 if (Validator.isNotNull(emailArticleApprovalDeniedSubject)) {
393 return emailArticleApprovalDeniedSubject;
394 }
395 else {
396 return ContentUtil.get(PropsUtil.get(
397 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_SUBJECT));
398 }
399 }
400
401 public static boolean getEmailArticleApprovalGrantedEnabled(
402 PortletPreferences preferences) {
403
404 String emailArticleApprovalGrantedEnabled = preferences.getValue(
405 "email-article-approval-granted-enabled", StringPool.BLANK);
406
407 if (Validator.isNotNull(emailArticleApprovalGrantedEnabled)) {
408 return GetterUtil.getBoolean(emailArticleApprovalGrantedEnabled);
409 }
410 else {
411 return GetterUtil.getBoolean(PropsUtil.get(
412 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_ENABLED));
413 }
414 }
415
416 public static String getEmailArticleApprovalGrantedBody(
417 PortletPreferences preferences) {
418
419 String emailArticleApprovalGrantedBody = preferences.getValue(
420 "email-article-approval-granted-body", StringPool.BLANK);
421
422 if (Validator.isNotNull(emailArticleApprovalGrantedBody)) {
423 return emailArticleApprovalGrantedBody;
424 }
425 else {
426 return ContentUtil.get(PropsUtil.get(
427 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_BODY));
428 }
429 }
430
431 public static String getEmailArticleApprovalGrantedSubject(
432 PortletPreferences preferences) {
433
434 String emailArticleApprovalGrantedSubject = preferences.getValue(
435 "email-article-approval-granted-subject", StringPool.BLANK);
436
437 if (Validator.isNotNull(emailArticleApprovalGrantedSubject)) {
438 return emailArticleApprovalGrantedSubject;
439 }
440 else {
441 return ContentUtil.get(PropsUtil.get(
442 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_SUBJECT));
443 }
444 }
445
446 public static boolean getEmailArticleApprovalRequestedEnabled(
447 PortletPreferences preferences) {
448
449 String emailArticleApprovalRequestedEnabled = preferences.getValue(
450 "email-article-approval-requested-enabled", StringPool.BLANK);
451
452 if (Validator.isNotNull(emailArticleApprovalRequestedEnabled)) {
453 return GetterUtil.getBoolean(emailArticleApprovalRequestedEnabled);
454 }
455 else {
456 return GetterUtil.getBoolean(PropsUtil.get(
457 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_ENABLED));
458 }
459 }
460
461 public static String getEmailArticleApprovalRequestedBody(
462 PortletPreferences preferences) {
463
464 String emailArticleApprovalRequestedBody = preferences.getValue(
465 "email-article-approval-requested-body", StringPool.BLANK);
466
467 if (Validator.isNotNull(emailArticleApprovalRequestedBody)) {
468 return emailArticleApprovalRequestedBody;
469 }
470 else {
471 return ContentUtil.get(PropsUtil.get(
472 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_BODY));
473 }
474 }
475
476 public static String getEmailArticleApprovalRequestedSubject(
477 PortletPreferences preferences) {
478
479 String emailArticleApprovalRequestedSubject = preferences.getValue(
480 "email-article-approval-requested-subject", StringPool.BLANK);
481
482 if (Validator.isNotNull(emailArticleApprovalRequestedSubject)) {
483 return emailArticleApprovalRequestedSubject;
484 }
485 else {
486 return ContentUtil.get(PropsUtil.get(
487 PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_SUBJECT));
488 }
489 }
490
491 public static boolean getEmailArticleReviewEnabled(
492 PortletPreferences preferences) {
493
494 String emailArticleReviewEnabled = preferences.getValue(
495 "email-article-review-enabled", StringPool.BLANK);
496
497 if (Validator.isNotNull(emailArticleReviewEnabled)) {
498 return GetterUtil.getBoolean(emailArticleReviewEnabled);
499 }
500 else {
501 return GetterUtil.getBoolean(PropsUtil.get(
502 PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_ENABLED));
503 }
504 }
505
506 public static String getEmailArticleReviewBody(
507 PortletPreferences preferences) {
508
509 String emailArticleReviewBody = preferences.getValue(
510 "email-article-review-body", StringPool.BLANK);
511
512 if (Validator.isNotNull(emailArticleReviewBody)) {
513 return emailArticleReviewBody;
514 }
515 else {
516 return ContentUtil.get(PropsUtil.get(
517 PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_BODY));
518 }
519 }
520
521 public static String getEmailArticleReviewSubject(
522 PortletPreferences preferences) {
523
524 String emailArticleReviewSubject = preferences.getValue(
525 "email-article-review-subject", StringPool.BLANK);
526
527 if (Validator.isNotNull(emailArticleReviewSubject)) {
528 return emailArticleReviewSubject;
529 }
530 else {
531 return ContentUtil.get(PropsUtil.get(
532 PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_SUBJECT));
533 }
534 }
535
536 public static Stack<JournalArticle> getRecentArticles(
537 PortletRequest portletRequest) {
538
539 PortletSession portletSession = portletRequest.getPortletSession();
540
541 Stack<JournalArticle> recentArticles =
542 (Stack<JournalArticle>)portletSession.getAttribute(
543 WebKeys.JOURNAL_RECENT_ARTICLES);
544
545 if (recentArticles == null) {
546 recentArticles = new FiniteUniqueStack<JournalArticle>(
547 MAX_STACK_SIZE);
548
549 portletSession.setAttribute(
550 WebKeys.JOURNAL_RECENT_ARTICLES, recentArticles);
551 }
552
553 return recentArticles;
554 }
555
556 public static Stack<JournalStructure> getRecentStructures(
557 PortletRequest portletRequest) {
558
559 PortletSession portletSession = portletRequest.getPortletSession();
560
561 Stack<JournalStructure> recentStructures =
562 (Stack<JournalStructure>)portletSession.getAttribute(
563 WebKeys.JOURNAL_RECENT_STRUCTURES);
564
565 if (recentStructures == null) {
566 recentStructures = new FiniteUniqueStack<JournalStructure>(
567 MAX_STACK_SIZE);
568
569 portletSession.setAttribute(
570 WebKeys.JOURNAL_RECENT_STRUCTURES, recentStructures);
571 }
572
573 return recentStructures;
574 }
575
576 public static Stack<JournalTemplate> getRecentTemplates(
577 PortletRequest portletRequest) {
578
579 PortletSession portletSession = portletRequest.getPortletSession();
580
581 Stack<JournalTemplate> recentTemplates =
582 (Stack<JournalTemplate>)portletSession.getAttribute(
583 WebKeys.JOURNAL_RECENT_TEMPLATES);
584
585 if (recentTemplates == null) {
586 recentTemplates = new FiniteUniqueStack<JournalTemplate>(
587 MAX_STACK_SIZE);
588
589 portletSession.setAttribute(
590 WebKeys.JOURNAL_RECENT_TEMPLATES, recentTemplates);
591 }
592
593 return recentTemplates;
594 }
595
596 public static String getTemplateScript(
597 long groupId, String templateId, Map<String, String> tokens,
598 String languageId)
599 throws PortalException, SystemException {
600
601 return getTemplateScript(groupId, templateId, tokens, languageId, true);
602 }
603
604 public static String getTemplateScript(
605 long groupId, String templateId, Map<String, String> tokens,
606 String languageId, boolean transform)
607 throws PortalException, SystemException {
608
609 JournalTemplate template = JournalTemplateLocalServiceUtil.getTemplate(
610 groupId, templateId);
611
612 return getTemplateScript(template, tokens, languageId, transform);
613 }
614
615 public static String getTemplateScript(
616 JournalTemplate template, Map<String, String> tokens, String languageId,
617 boolean transform) {
618
619 String script = template.getXsl();
620
621 if (transform) {
622
623
625 String[] listeners =
626 PropsUtil.getArray(PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
627
628 for (int i = 0; i < listeners.length; i++) {
629 TransformerListener listener = null;
630
631 try {
632 listener =
633 (TransformerListener)Class.forName(
634 listeners[i]).newInstance();
635
636 listener.setTemplateDriven(true);
637 listener.setLanguageId(languageId);
638 listener.setTokens(tokens);
639 }
640 catch (Exception e) {
641 _log.error(e, e);
642 }
643
644
646 if (listener != null) {
647 script = listener.onScript(script);
648 }
649 }
650 }
651
652 return script;
653 }
654
655 public static Map<String, String> getTokens(
656 long groupId, ThemeDisplay themeDisplay) {
657
658 return getTokens(groupId, themeDisplay, null);
659 }
660
661 public static Map<String, String> getTokens(
662 long groupId, ThemeDisplay themeDisplay, String xmlRequest) {
663
664 Map<String, String> tokens = new HashMap<String, String>();
665
666 if (themeDisplay != null) {
667 _populateTokens(tokens, groupId, themeDisplay);
668 }
669 else if (Validator.isNotNull(xmlRequest)) {
670 try {
671 _populateTokens(tokens, groupId, xmlRequest);
672 }
673 catch (Exception e) {
674 if (_log.isWarnEnabled()) {
675 _log.warn(e, e);
676 }
677 }
678 }
679
680 return tokens;
681 }
682
683 public static String getUrlTitle(long id, String title) {
684 title = title.trim().toLowerCase();
685
686 if (Validator.isNull(title) || Validator.isNumber(title) ||
687 title.equals("rss")) {
688
689 return String.valueOf(id);
690 }
691 else {
692 return FriendlyURLNormalizer.normalize(
693 title, _URL_TITLE_REPLACE_CHARS);
694 }
695 }
696
697 public static String mergeArticleContent(
698 String curContent, String newContent) {
699
700 try {
701 Document curDocument = SAXReaderUtil.read(curContent);
702 Document newDocument = SAXReaderUtil.read(newContent);
703
704 Element curRoot = curDocument.getRootElement();
705 Element newRoot = newDocument.getRootElement();
706
707 curRoot.addAttribute(
708 "default-locale",
709 newRoot.attributeValue("default-locale"));
710 curRoot.addAttribute(
711 "available-locales",
712 newRoot.attributeValue("available-locales"));
713
714 _mergeArticleContentUpdate(
715 curDocument, newRoot,
716 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
717 _mergeArticleContentDelete(curRoot, newDocument);
718
719 curContent = JournalUtil.formatXML(curDocument);
720 }
721 catch (Exception e) {
722 _log.error(e, e);
723 }
724
725 return curContent;
726 }
727
728 public static String removeArticleLocale(
729 String content, String languageId) {
730
731 try {
732 Document doc = SAXReaderUtil.read(content);
733
734 Element root = doc.getRootElement();
735
736 String availableLocales = root.attributeValue("available-locales");
737
738 if (availableLocales == null) {
739 return content;
740 }
741
742 availableLocales = StringUtil.remove(availableLocales, languageId);
743
744 if (availableLocales.endsWith(",")) {
745 availableLocales = availableLocales.substring(
746 0, availableLocales.length() - 1);
747 }
748
749 root.addAttribute("available-locales", availableLocales);
750
751 removeArticleLocale(root, languageId);
752
753 content = formatXML(doc);
754 }
755 catch (Exception e) {
756 _log.error(e, e);
757 }
758
759 return content;
760 }
761
762 public static void removeArticleLocale(Element el, String languageId)
763 throws PortalException, SystemException {
764
765 for (Element dynamicEl : el.elements("dynamic-element")) {
766 for (Element dynamicContentEl :
767 dynamicEl.elements("dynamic-content")) {
768
769 String curLanguageId = GetterUtil.getString(
770 dynamicContentEl.attributeValue("language-id"));
771
772 if (curLanguageId.equals(languageId)) {
773 long id = GetterUtil.getLong(
774 dynamicContentEl.attributeValue("id"));
775
776 if (id > 0) {
777 ImageLocalServiceUtil.deleteImage(id);
778 }
779
780 dynamicContentEl.detach();
781 }
782 }
783
784 removeArticleLocale(dynamicEl, languageId);
785 }
786 }
787
788 public static String removeOldContent(String content, String xsd) {
789 try {
790 Document contentDoc = SAXReaderUtil.read(content);
791 Document xsdDoc = SAXReaderUtil.read(xsd);
792
793 Element contentRoot = contentDoc.getRootElement();
794
795 Stack<String> path = new Stack<String>();
796
797 path.push(contentRoot.getName());
798
799 _removeOldContent(path, contentRoot, xsdDoc);
800
801 content = formatXML(contentDoc);
802 }
803 catch (Exception e) {
804 _log.error(e, e);
805 }
806
807 return content;
808 }
809
810 public static void removeRecentArticle(
811 PortletRequest portletRequest, String articleId) {
812
813 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
814
815 Iterator<JournalArticle> itr = stack.iterator();
816
817 while (itr.hasNext()) {
818 JournalArticle journalArticle = itr.next();
819
820 if (journalArticle.getArticleId().equals(articleId)) {
821 itr.remove();
822
823 break;
824 }
825 }
826 }
827
828 public static void removeRecentStructure(
829 PortletRequest portletRequest, String structureId) {
830
831 Stack<JournalStructure> stack = getRecentStructures(portletRequest);
832
833 Iterator<JournalStructure> itr = stack.iterator();
834
835 while (itr.hasNext()) {
836 JournalStructure journalStructure = itr.next();
837
838 if (journalStructure.getStructureId().equals(structureId)) {
839 itr.remove();
840
841 break;
842 }
843 }
844 }
845
846 public static void removeRecentTemplate(
847 PortletRequest portletRequest, String templateId) {
848
849 Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
850
851 Iterator<JournalTemplate> itr = stack.iterator();
852
853 while (itr.hasNext()) {
854 JournalTemplate journalTemplate = itr.next();
855
856 if (journalTemplate.getTemplateId().equals(templateId)) {
857 itr.remove();
858
859 break;
860 }
861 }
862 }
863
864 public static String transform(
865 Map<String, String> tokens, String viewMode, String languageId,
866 String xml, String script, String langType)
867 throws Exception {
868
869
871 if (_log.isDebugEnabled()) {
872 _log.debug("Language " + languageId);
873 }
874
875 if (Validator.isNull(viewMode)) {
876 viewMode = Constants.VIEW;
877 }
878
879 if (_logTokens.isDebugEnabled()) {
880 String tokensString = PropertiesUtil.list(tokens);
881
882 _logTokens.debug(tokensString);
883 }
884
885 if (_logTransformBefore.isDebugEnabled()) {
886 _logTransformBefore.debug(xml);
887 }
888
889 List<TransformerListener> listenersList =
890 new ArrayList<TransformerListener>();
891
892 String[] listeners = PropsUtil.getArray(
893 PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
894
895 for (int i = 0; i < listeners.length; i++) {
896 TransformerListener listener = null;
897
898 try {
899 if (_log.isDebugEnabled()) {
900 _log.debug("Instantiate listener " + listeners[i]);
901 }
902
903 boolean templateDriven = Validator.isNotNull(langType);
904
905 listener = (TransformerListener)Class.forName(
906 listeners[i]).newInstance();
907
908 listener.setTemplateDriven(templateDriven);
909 listener.setLanguageId(languageId);
910 listener.setTokens(tokens);
911
912 listenersList.add(listener);
913 }
914 catch (Exception e) {
915 _log.error(e, e);
916 }
917
918
920 if (_logXmlBeforeListener.isDebugEnabled()) {
921 _logXmlBeforeListener.debug(xml);
922 }
923
924 if (listener != null) {
925 xml = listener.onXml(xml);
926
927 if (_logXmlAfterListener.isDebugEnabled()) {
928 _logXmlAfterListener.debug(xml);
929 }
930 }
931
932
934 if (_logScriptBeforeListener.isDebugEnabled()) {
935 _logScriptBeforeListener.debug(script);
936 }
937
938 if (listener != null) {
939 script = listener.onScript(script);
940
941 if (_logScriptAfterListener.isDebugEnabled()) {
942 _logScriptAfterListener.debug(script);
943 }
944 }
945 }
946
947
949 String output = null;
950
951 if (Validator.isNull(langType)) {
952 output = LocalizationUtil.getLocalization(xml, languageId);
953 }
954 else {
955 String templateParserClassName = PropsUtil.get(
956 PropsKeys.JOURNAL_TEMPLATE_LANGUAGE_PARSER,
957 new Filter(langType));
958
959 if (_log.isDebugEnabled()) {
960 _log.debug(
961 "Template parser class name " + templateParserClassName);
962 }
963
964 if (Validator.isNotNull(templateParserClassName)) {
965 TemplateParser templateParser =
966 (TemplateParser)InstancePool.get(templateParserClassName);
967
968 if (templateParser == null) {
969 throw new TransformException(
970 "No template parser found for " +
971 templateParserClassName);
972 }
973
974 output = templateParser.transform(
975 tokens, viewMode, languageId, xml, script);
976 }
977 }
978
979
981 for (int i = 0; i < listenersList.size(); i++) {
982 TransformerListener listener = listenersList.get(i);
983
984
986 if (_logOutputBeforeListener.isDebugEnabled()) {
987 _logOutputBeforeListener.debug(output);
988 }
989
990 output = listener.onOutput(output);
991
992 if (_logOutputAfterListener.isDebugEnabled()) {
993 _logOutputAfterListener.debug(output);
994 }
995 }
996
997 if (_logTransfromAfter.isDebugEnabled()) {
998 _logTransfromAfter.debug(output);
999 }
1000
1001 return output;
1002 }
1003
1004 private static void _addElementOptions (
1005 Element curContentElement, Element newContentElement) {
1006
1007 List<Element> newElementOptions = newContentElement.elements("option");
1008
1009 for (Element newElementOption : newElementOptions) {
1010 Element curElementOption = SAXReaderUtil.createElement("option");
1011
1012 curElementOption.addCDATA(newElementOption.getText());
1013
1014 curContentElement.add(curElementOption);
1015 }
1016 }
1017
1018 private static Element _getElementByInstanceId(
1019 Document document, String instanceId) {
1020
1021 XPath xPathSelector = SAXReaderUtil.createXPath(
1022 "//dynamic-element[@instance-id='" + instanceId + "']");
1023
1024 List<Node> nodes = xPathSelector.selectNodes(document);
1025
1026 if (nodes.size() == 1) {
1027 return (Element)nodes.get(0);
1028 }
1029 else {
1030 return null;
1031 }
1032 }
1033
1034 private static void _mergeArticleContentDelete(
1035 Element curParentElement, Document newDocument)
1036 throws Exception {
1037
1038 List<Element> curElements = curParentElement.elements(
1039 "dynamic-element");
1040
1041 for (int i = 0; i < curElements.size(); i++) {
1042 Element curElement = curElements.get(i);
1043
1044 _mergeArticleContentDelete(curElement, newDocument);
1045
1046 String instanceId = curElement.attributeValue("instance-id");
1047
1048 Element newElement = _getElementByInstanceId(
1049 newDocument, instanceId);
1050
1051 if (newElement == null) {
1052 curElement.detach();
1053
1054 String type = curElement.attributeValue("type");
1055
1056 if (type.equals("image")) {
1057 _mergeArticleContentDeleteImages(
1058 curElement.elements("dynamic-content"));
1059 }
1060 }
1061 }
1062 }
1063
1064 private static void _mergeArticleContentDeleteImages(List<Element> elements)
1065 throws Exception {
1066
1067 for (Element element : elements) {
1068 long articleImageId = GetterUtil.getLong(
1069 element.attributeValue("id"));
1070
1071 JournalArticleImageLocalServiceUtil.deleteArticleImage(
1072 articleImageId);
1073 }
1074 }
1075
1076 private static void _mergeArticleContentUpdate(
1077 Document curDocument, Element newParentElement,
1078 String defaultLocale)
1079 throws Exception {
1080
1081 List<Element> newElements = newParentElement.elements(
1082 "dynamic-element");
1083
1084 for (int i = 0; i < newElements.size(); i++) {
1085 Element newElement = newElements.get(i);
1086
1087 _mergeArticleContentUpdate(
1088 curDocument, newParentElement, newElement, i, defaultLocale);
1089 }
1090 }
1091
1092 private static void _mergeArticleContentUpdate(
1093 Document curDocument, Element newParentElement, Element newElement,
1094 int pos, String defaultLocale)
1095 throws Exception {
1096
1097 _mergeArticleContentUpdate(curDocument, newElement, defaultLocale);
1098
1099 String instanceId = newElement.attributeValue("instance-id");
1100
1101 Element curElement = _getElementByInstanceId(curDocument, instanceId);
1102
1103 if (curElement != null) {
1104 _mergeArticleContentUpdate(curElement, newElement, defaultLocale);
1105 }
1106 else {
1107 String parentInstanceId = newParentElement.attributeValue(
1108 "instance-id");
1109
1110 if (Validator.isNull(parentInstanceId)) {
1111 Element curRoot = curDocument.getRootElement();
1112
1113 List<Element> curRootElements = curRoot.elements();
1114
1115 curRootElements.add(pos, newElement.createCopy());
1116 }
1117 else {
1118 Element curParentElement = _getElementByInstanceId(
1119 curDocument, parentInstanceId);
1120
1121 if (curParentElement != null) {
1122 List<Element> curParentElements =
1123 curParentElement.elements();
1124
1125 curParentElements.add(pos, newElement.createCopy());
1126 }
1127 }
1128 }
1129 }
1130
1131 private static void _mergeArticleContentUpdate(
1132 Element curElement, Element newElement, String defaultLocale) {
1133
1134 Element newContentElement = newElement.elements(
1135 "dynamic-content").get(0);
1136
1137 String newLanguageId = newContentElement.attributeValue("language-id");
1138 String newValue = newContentElement.getText();
1139
1140 List<Element> curContentElements = curElement.elements(
1141 "dynamic-content");
1142
1143 if (Validator.isNull(newLanguageId)) {
1144 for (Element curContentElement : curContentElements) {
1145 curContentElement.detach();
1146 }
1147
1148 Element curContentElement = SAXReaderUtil.createElement(
1149 "dynamic-content");
1150
1151 if (newContentElement.element("option") != null) {
1152 _addElementOptions(curContentElement, newContentElement);
1153 }
1154 else {
1155 curContentElement.addCDATA(newValue);
1156 }
1157
1158 curElement.add(curContentElement);
1159 }
1160 else {
1161 boolean alreadyExists = false;
1162
1163 for (Element curContentElement : curContentElements) {
1164 String curLanguageId = curContentElement.attributeValue(
1165 "language-id");
1166
1167 if (newLanguageId.equals(curLanguageId)) {
1168 alreadyExists = true;
1169
1170 curContentElement.clearContent();
1171
1172 if (newContentElement.element("option") != null) {
1173 _addElementOptions(
1174 curContentElement, newContentElement);
1175 }
1176 else {
1177 curContentElement.addCDATA(newValue);
1178 }
1179
1180 break;
1181 }
1182 }
1183
1184 if (!alreadyExists) {
1185 Element curContentElement = curContentElements.get(0);
1186
1187 String curLanguageId = curContentElement.attributeValue(
1188 "language-id");
1189
1190 if (Validator.isNull(curLanguageId)) {
1191 curContentElement.detach();
1192 }
1193
1194 curElement.add(newContentElement.createCopy());
1195 }
1196 }
1197 }
1198
1199 private static void _populateTokens(
1200 Map<String, String> tokens, long groupId, String xmlRequest)
1201 throws Exception {
1202
1203 Document request = SAXReaderUtil.read(xmlRequest);
1204
1205 Element root = request.getRootElement();
1206
1207 Element themeDisplayEl = root.element("theme-display");
1208
1209 Layout layout = LayoutLocalServiceUtil.getLayout(
1210 GetterUtil.getLong(themeDisplayEl.elementText("plid")));
1211
1212 Group group = layout.getGroup();
1213
1214 LayoutSet layoutSet = layout.getLayoutSet();
1215
1216 String friendlyUrlCurrent = null;
1217
1218 if (layout.isPublicLayout()) {
1219 friendlyUrlCurrent = themeDisplayEl.elementText(
1220 "path-friendly-url-public");
1221 }
1222 else if (group.isUserGroup()) {
1223 friendlyUrlCurrent = themeDisplayEl.elementText(
1224 "path-friendly-url-private-user");
1225 }
1226 else {
1227 friendlyUrlCurrent = themeDisplayEl.elementText(
1228 "path-friendly-url-private-group");
1229 }
1230
1231 String layoutSetFriendlyUrl = StringPool.BLANK;
1232
1233 String virtualHost = layoutSet.getVirtualHost();
1234
1235 if (Validator.isNull(virtualHost) ||
1236 !virtualHost.equals(themeDisplayEl.elementText("server-name"))) {
1237
1238 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1239 }
1240
1241 tokens.put("cdn_host", themeDisplayEl.elementText("cdn-host"));
1242 tokens.put("company_id", themeDisplayEl.elementText("company-id"));
1243 tokens.put("friendly_url_current", friendlyUrlCurrent);
1244 tokens.put(
1245 "friendly_url_private_group",
1246 themeDisplayEl.elementText("path-friendly-url-private-group"));
1247 tokens.put(
1248 "friendly_url_private_user",
1249 themeDisplayEl.elementText("path-friendly-url-private-user"));
1250 tokens.put(
1251 "friendly_url_public",
1252 themeDisplayEl.elementText("path-friendly-url-public"));
1253 tokens.put("group_friendly_url", group.getFriendlyURL());
1254 tokens.put("group_id", String.valueOf(groupId));
1255 tokens.put("image_path", themeDisplayEl.elementText("path-image"));
1256 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1257 tokens.put("main_path", themeDisplayEl.elementText("path-main"));
1258 tokens.put("portal_ctx", themeDisplayEl.elementText("path-context"));
1259 tokens.put(
1260 "portal_url",
1261 HttpUtil.removeProtocol(themeDisplayEl.elementText("url-portal")));
1262 tokens.put(
1263 "protocol",
1264 HttpUtil.getProtocol(themeDisplayEl.elementText("url-portal")));
1265 tokens.put("root_path", themeDisplayEl.elementText("path-context"));
1266 tokens.put(
1267 "theme_image_path",
1268 themeDisplayEl.elementText("path-theme-images"));
1269
1270
1272 tokens.put(
1273 "friendly_url",
1274 themeDisplayEl.elementText("path-friendly-url-public"));
1275 tokens.put(
1276 "friendly_url_private",
1277 themeDisplayEl.elementText("path-friendly-url-private-group"));
1278 tokens.put(
1279 "page_url", themeDisplayEl.elementText("path-friendly-url-public"));
1280 }
1281
1282 private static void _populateTokens(
1283 Map<String, String> tokens, long groupId, ThemeDisplay themeDisplay) {
1284
1285 Layout layout = themeDisplay.getLayout();
1286
1287 Group group = layout.getGroup();
1288
1289 LayoutSet layoutSet = layout.getLayoutSet();
1290
1291 String friendlyUrlCurrent = null;
1292
1293 if (layout.isPublicLayout()) {
1294 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPublic();
1295 }
1296 else if (group.isUserGroup()) {
1297 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateUser();
1298 }
1299 else {
1300 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateGroup();
1301 }
1302
1303 String layoutSetFriendlyUrl = StringPool.BLANK;
1304
1305 String virtualHost = layoutSet.getVirtualHost();
1306
1307 if (Validator.isNull(virtualHost) ||
1308 !virtualHost.equals(themeDisplay.getServerName())) {
1309
1310 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1311 }
1312
1313 tokens.put("cdn_host", themeDisplay.getCDNHost());
1314 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
1315 tokens.put("friendly_url_current", friendlyUrlCurrent);
1316 tokens.put(
1317 "friendly_url_private_group",
1318 themeDisplay.getPathFriendlyURLPrivateGroup());
1319 tokens.put(
1320 "friendly_url_private_user",
1321 themeDisplay.getPathFriendlyURLPrivateUser());
1322 tokens.put(
1323 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
1324 tokens.put("group_friendly_url", group.getFriendlyURL());
1325 tokens.put("group_id", String.valueOf(groupId));
1326 tokens.put("image_path", themeDisplay.getPathImage());
1327 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1328 tokens.put("main_path", themeDisplay.getPathMain());
1329 tokens.put("portal_ctx", themeDisplay.getPathContext());
1330 tokens.put(
1331 "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
1332 tokens.put(
1333 "protocol", HttpUtil.getProtocol(themeDisplay.getURLPortal()));
1334 tokens.put("root_path", themeDisplay.getPathContext());
1335 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
1336
1337
1339 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
1340 tokens.put(
1341 "friendly_url_private",
1342 themeDisplay.getPathFriendlyURLPrivateGroup());
1343 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
1344 }
1345
1346 private static void _removeOldContent(
1347 Stack<String> path, Element contentEl, Document xsdDoc)
1348 throws SystemException {
1349
1350 String elPath = "";
1351
1352 for (int i = 0; i < path.size(); i++) {
1353 elPath += "/" + path.elementAt(i);
1354 }
1355
1356 for (int i = 0; i < contentEl.nodeCount(); i++) {
1357 Node contentNode = contentEl.node(i);
1358
1359 if (contentNode instanceof Element) {
1360 _removeOldContent(path, (Element)contentNode, xsdDoc, elPath);
1361 }
1362 }
1363 }
1364
1365 private static void _removeOldContent(
1366 Stack<String> path, Element contentEl, Document xsdDoc,
1367 String elPath)
1368 throws SystemException {
1369
1370 String name = contentEl.attributeValue("name");
1371
1372 if (Validator.isNull(name)) {
1373 return;
1374 }
1375
1376 String localPath = "dynamic-element[@name='" + name + "']";
1377
1378 String fullPath = elPath + "/" + localPath;
1379
1380 XPath xPathSelector = SAXReaderUtil.createXPath(fullPath);
1381
1382 List<Node> curNodes = xPathSelector.selectNodes(xsdDoc);
1383
1384 if (curNodes.size() == 0) {
1385 contentEl.detach();
1386 }
1387
1388 path.push(localPath);
1389
1390 _removeOldContent(path, contentEl, xsdDoc);
1391
1392 path.pop();
1393 }
1394
1395 private static final char[] _URL_TITLE_REPLACE_CHARS = new char[] {
1396 '.', '/'
1397 };
1398
1399 private static Log _log = LogFactoryUtil.getLog(JournalUtil.class);
1400
1401 private static Log _logOutputAfterListener = LogFactoryUtil.getLog(
1402 JournalUtil.class.getName() + ".OutputAfterListener");
1403
1404 private static Log _logOutputBeforeListener = LogFactoryUtil.getLog(
1405 JournalUtil.class.getName() + ".OutputBeforeListener");
1406
1407 private static Log _logScriptAfterListener = LogFactoryUtil.getLog(
1408 JournalUtil.class.getName() + ".ScriptAfterListener");
1409
1410 private static Log _logScriptBeforeListener = LogFactoryUtil.getLog(
1411 JournalUtil.class.getName() + ".ScriptBeforeListener");
1412
1413 private static Log _logTransfromAfter = LogFactoryUtil.getLog(
1414 JournalUtil.class.getName() + ".TransformAfter");
1415
1416 private static Log _logTransformBefore = LogFactoryUtil.getLog(
1417 JournalUtil.class.getName() + ".BeforeTransform");
1418
1419 private static Log _logTokens = LogFactoryUtil.getLog(
1420 JournalUtil.class.getName() + ".Tokens");
1421
1422 private static Log _logXmlAfterListener = LogFactoryUtil.getLog(
1423 JournalUtil.class.getName() + ".XmlAfterListener");
1424
1425 private static Log _logXmlBeforeListener = LogFactoryUtil.getLog(
1426 JournalUtil.class.getName() + ".XmlBeforeListener");
1427
1428}