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