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