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