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