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