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.Constants;
30 import com.liferay.portal.kernel.util.GetterUtil;
31 import com.liferay.portal.kernel.util.HttpUtil;
32 import com.liferay.portal.kernel.util.LocaleUtil;
33 import com.liferay.portal.kernel.util.OrderByComparator;
34 import com.liferay.portal.kernel.util.PropertiesUtil;
35 import com.liferay.portal.kernel.util.PropsKeys;
36 import com.liferay.portal.kernel.util.StringPool;
37 import com.liferay.portal.kernel.util.StringUtil;
38 import com.liferay.portal.kernel.util.Time;
39 import com.liferay.portal.kernel.util.Validator;
40 import com.liferay.portal.kernel.xml.Document;
41 import com.liferay.portal.kernel.xml.Element;
42 import com.liferay.portal.kernel.xml.Node;
43 import com.liferay.portal.kernel.xml.SAXReaderUtil;
44 import com.liferay.portal.kernel.xml.XPath;
45 import com.liferay.portal.model.Group;
46 import com.liferay.portal.model.Layout;
47 import com.liferay.portal.model.LayoutSet;
48 import com.liferay.portal.model.User;
49 import com.liferay.portal.service.ImageLocalServiceUtil;
50 import com.liferay.portal.service.LayoutLocalServiceUtil;
51 import com.liferay.portal.service.UserLocalServiceUtil;
52 import com.liferay.portal.theme.ThemeDisplay;
53 import com.liferay.portal.util.ContentUtil;
54 import com.liferay.portal.util.PropsUtil;
55 import com.liferay.portal.util.WebKeys;
56 import com.liferay.portlet.journal.model.JournalArticle;
57 import com.liferay.portlet.journal.model.JournalStructure;
58 import com.liferay.portlet.journal.model.JournalTemplate;
59 import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
60 import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
61 import com.liferay.portlet.journal.service.JournalArticleImageLocalServiceUtil;
62 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
63 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
64 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
65 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
66 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
67 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
68 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
69 import com.liferay.util.FiniteUniqueStack;
70 import com.liferay.util.LocalizationUtil;
71 import com.liferay.util.xml.XMLFormatter;
72
73 import java.io.IOException;
74
75 import java.util.ArrayList;
76 import java.util.Date;
77 import java.util.HashMap;
78 import java.util.Iterator;
79 import java.util.List;
80 import java.util.Map;
81 import java.util.Stack;
82
83 import javax.portlet.PortletPreferences;
84 import javax.portlet.PortletRequest;
85 import javax.portlet.PortletSession;
86
87
94 public class JournalUtil {
95
96 public static final int MAX_STACK_SIZE = 20;
97
98 public static final String XML_INDENT = " ";
99
100 public static void addRecentArticle(
101 PortletRequest portletRequest, JournalArticle article) {
102
103 if (article != null) {
104 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
105
106 stack.push(article);
107 }
108 }
109
110 public static void addRecentStructure(
111 PortletRequest portletRequest, JournalStructure structure) {
112
113 if (structure != null) {
114 Stack<JournalStructure> stack = getRecentStructures(portletRequest);
115
116 stack.push(structure);
117 }
118 }
119
120 public static void addRecentTemplate(
121 PortletRequest portletRequest, JournalTemplate template) {
122
123 if (template != null) {
124 Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
125
126 stack.push(template);
127 }
128 }
129
130 public static void addReservedEl(
131 Element root, Map<String, String> tokens, String name, double value) {
132
133 addReservedEl(root, tokens, name, String.valueOf(value));
134 }
135
136 public static void addReservedEl(
137 Element root, Map<String, String> tokens, String name, Date value) {
138
139 addReservedEl(root, tokens, name, Time.getRFC822(value));
140 }
141
142 public static void addReservedEl(
143 Element root, Map<String, String> tokens, String name, String value) {
144
145
147 if (root != null) {
148 Element dynamicEl = SAXReaderUtil.createElement("dynamic-element");
149
150 dynamicEl.add(
151 SAXReaderUtil.createAttribute(dynamicEl, "name", name));
152 dynamicEl.add(
153 SAXReaderUtil.createAttribute(dynamicEl, "type", "text"));
154
155 Element dynamicContent = SAXReaderUtil.createElement(
156 "dynamic-content");
157
158 dynamicContent.setText(value);
160
161 dynamicEl.add(dynamicContent);
162
163 root.add(dynamicEl);
164 }
165
166
168 tokens.put(
169 StringUtil.replace(name, StringPool.DASH, StringPool.UNDERLINE),
170 value);
171 }
172
173 public static void addAllReservedEls(
174 Element root, Map<String, String> tokens, JournalArticle article) {
175
176 JournalUtil.addReservedEl(
177 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_ID,
178 article.getArticleId());
179
180 JournalUtil.addReservedEl(
181 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_VERSION,
182 article.getVersion());
183
184 JournalUtil.addReservedEl(
185 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TITLE,
186 article.getTitle());
187
188 JournalUtil.addReservedEl(
189 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_URL_TITLE,
190 article.getUrlTitle());
191
192 JournalUtil.addReservedEl(
193 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_DESCRIPTION,
194 article.getDescription());
195
196 JournalUtil.addReservedEl(
197 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TYPE,
198 article.getType());
199
200 JournalUtil.addReservedEl(
201 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_CREATE_DATE,
202 article.getCreateDate());
203
204 JournalUtil.addReservedEl(
205 root, tokens,
206 JournalStructureImpl.RESERVED_ARTICLE_MODIFIED_DATE,
207 article.getModifiedDate());
208
209 if (article.getDisplayDate() != null) {
210 JournalUtil.addReservedEl(
211 root, tokens,
212 JournalStructureImpl.RESERVED_ARTICLE_DISPLAY_DATE,
213 article.getDisplayDate());
214 }
215
216 JournalUtil.addReservedEl(
217 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_SMALL_IMAGE_URL,
218 article.getSmallImageURL());
219
220 JournalUtil.addReservedEl(
221 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_ID,
222 String.valueOf(article.getUserId()));
223
224 String userName = StringPool.BLANK;
225 String userEmailAddress = StringPool.BLANK;
226 String userComments = StringPool.BLANK;
227 String userJobTitle = StringPool.BLANK;
228
229 User user = null;
230
231 try {
232 user = UserLocalServiceUtil.getUserById(article.getUserId());
233
234 userName = user.getFullName();
235 userEmailAddress = user.getEmailAddress();
236 userComments = user.getComments();
237 userJobTitle = user.getJobTitle();
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 preferences) {
325 String emailFromAddress = PropsUtil.get(
326 PropsKeys.JOURNAL_EMAIL_FROM_ADDRESS);
327
328 return preferences.getValue("email-from-address", emailFromAddress);
329 }
330
331 public static String getEmailFromName(PortletPreferences preferences) {
332 String emailFromName = PropsUtil.get(
333 PropsKeys.JOURNAL_EMAIL_FROM_NAME);
334
335 return preferences.getValue("email-from-name", emailFromName);
336 }
337
338 public static boolean getEmailArticleApprovalDeniedEnabled(
339 PortletPreferences preferences) {
340
341 String emailArticleApprovalDeniedEnabled = preferences.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 preferences) {
355
356 String emailArticleApprovalDeniedBody = preferences.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 preferences) {
370
371 String emailArticleApprovalDeniedSubject = preferences.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 preferences) {
385
386 String emailArticleApprovalGrantedEnabled = preferences.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 preferences) {
400
401 String emailArticleApprovalGrantedBody = preferences.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 preferences) {
415
416 String emailArticleApprovalGrantedSubject = preferences.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 preferences) {
430
431 String emailArticleApprovalRequestedEnabled = preferences.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 preferences) {
445
446 String emailArticleApprovalRequestedBody = preferences.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 preferences) {
460
461 String emailArticleApprovalRequestedSubject = preferences.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 preferences) {
475
476 String emailArticleReviewEnabled = preferences.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(
489 PortletPreferences preferences) {
490
491 String emailArticleReviewBody = preferences.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 preferences) {
505
506 String emailArticleReviewSubject = preferences.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 mergeArticleContent(
666 String curContent, String newContent) {
667
668 try {
669 Document curDocument = SAXReaderUtil.read(curContent);
670 Document newDocument = SAXReaderUtil.read(newContent);
671
672 Element curRoot = curDocument.getRootElement();
673 Element newRoot = newDocument.getRootElement();
674
675 curRoot.addAttribute(
676 "default-locale",
677 newRoot.attributeValue("default-locale"));
678 curRoot.addAttribute(
679 "available-locales",
680 newRoot.attributeValue("available-locales"));
681
682 _mergeArticleContentUpdate(
683 curDocument, newRoot,
684 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
685 _mergeArticleContentDelete(curRoot, newDocument);
686
687 curContent = JournalUtil.formatXML(curDocument);
688 }
689 catch (Exception e) {
690 _log.error(e, e);
691 }
692
693 return curContent;
694 }
695
696 public static String removeArticleLocale(
697 String content, String languageId) {
698
699 try {
700 Document doc = SAXReaderUtil.read(content);
701
702 Element root = doc.getRootElement();
703
704 String availableLocales = root.attributeValue("available-locales");
705
706 if (availableLocales == null) {
707 return content;
708 }
709
710 availableLocales = StringUtil.remove(availableLocales, languageId);
711
712 if (availableLocales.endsWith(",")) {
713 availableLocales = availableLocales.substring(
714 0, availableLocales.length() - 1);
715 }
716
717 root.addAttribute("available-locales", availableLocales);
718
719 removeArticleLocale(root, languageId);
720
721 content = formatXML(doc);
722 }
723 catch (Exception e) {
724 _log.error(e, e);
725 }
726
727 return content;
728 }
729
730 public static void removeArticleLocale(Element el, String languageId)
731 throws PortalException, SystemException {
732
733 for (Element dynamicEl : el.elements("dynamic-element")) {
734 for (Element dynamicContentEl :
735 dynamicEl.elements("dynamic-content")) {
736
737 String curLanguageId = GetterUtil.getString(
738 dynamicContentEl.attributeValue("language-id"));
739
740 if (curLanguageId.equals(languageId)) {
741 long id = GetterUtil.getLong(
742 dynamicContentEl.attributeValue("id"));
743
744 if (id > 0) {
745 ImageLocalServiceUtil.deleteImage(id);
746 }
747
748 dynamicContentEl.detach();
749 }
750 }
751
752 removeArticleLocale(dynamicEl, languageId);
753 }
754 }
755
756 public static String removeOldContent(String content, String xsd) {
757 try {
758 Document contentDoc = SAXReaderUtil.read(content);
759 Document xsdDoc = SAXReaderUtil.read(xsd);
760
761 Element contentRoot = contentDoc.getRootElement();
762
763 Stack<String> path = new Stack<String>();
764
765 path.push(contentRoot.getName());
766
767 _removeOldContent(path, contentRoot, xsdDoc);
768
769 content = formatXML(contentDoc);
770 }
771 catch (Exception e) {
772 _log.error(e, e);
773 }
774
775 return content;
776 }
777
778 public static void removeRecentArticle(
779 PortletRequest portletRequest, String articleId) {
780
781 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
782
783 Iterator<JournalArticle> itr = stack.iterator();
784
785 while (itr.hasNext()) {
786 JournalArticle journalArticle = itr.next();
787
788 if (journalArticle.getArticleId().equals(articleId)) {
789 itr.remove();
790
791 break;
792 }
793 }
794 }
795
796 public static void removeRecentStructure(
797 PortletRequest portletRequest, String structureId) {
798
799 Stack<JournalStructure> stack = getRecentStructures(portletRequest);
800
801 Iterator<JournalStructure> itr = stack.iterator();
802
803 while (itr.hasNext()) {
804 JournalStructure journalStructure = itr.next();
805
806 if (journalStructure.getStructureId().equals(structureId)) {
807 itr.remove();
808
809 break;
810 }
811 }
812 }
813
814 public static void removeRecentTemplate(
815 PortletRequest portletRequest, String templateId) {
816
817 Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
818
819 Iterator<JournalTemplate> itr = stack.iterator();
820
821 while (itr.hasNext()) {
822 JournalTemplate journalTemplate = itr.next();
823
824 if (journalTemplate.getTemplateId().equals(templateId)) {
825 itr.remove();
826
827 break;
828 }
829 }
830 }
831
832 public static String transform(
833 Map<String, String> tokens, String viewMode, String languageId,
834 String xml, String script, String langType)
835 throws Exception {
836
837
839 if (_log.isDebugEnabled()) {
840 _log.debug("Language " + languageId);
841 }
842
843 if (Validator.isNull(viewMode)) {
844 viewMode = Constants.VIEW;
845 }
846
847 if (_logTokens.isDebugEnabled()) {
848 String tokensString = PropertiesUtil.list(tokens);
849
850 _logTokens.debug(tokensString);
851 }
852
853 if (_logTransformBefore.isDebugEnabled()) {
854 _logTransformBefore.debug(xml);
855 }
856
857 List<TransformerListener> listenersList =
858 new ArrayList<TransformerListener>();
859
860 String[] listeners = PropsUtil.getArray(
861 PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
862
863 for (int i = 0; i < listeners.length; i++) {
864 TransformerListener listener = null;
865
866 try {
867 if (_log.isDebugEnabled()) {
868 _log.debug("Instantiate listener " + listeners[i]);
869 }
870
871 boolean templateDriven = Validator.isNotNull(langType);
872
873 listener = (TransformerListener)Class.forName(
874 listeners[i]).newInstance();
875
876 listener.setTemplateDriven(templateDriven);
877 listener.setLanguageId(languageId);
878 listener.setTokens(tokens);
879
880 listenersList.add(listener);
881 }
882 catch (Exception e) {
883 _log.error(e, e);
884 }
885
886
888 if (_logXmlBeforeListener.isDebugEnabled()) {
889 _logXmlBeforeListener.debug(xml);
890 }
891
892 if (listener != null) {
893 xml = listener.onXml(xml);
894
895 if (_logXmlAfterListener.isDebugEnabled()) {
896 _logXmlAfterListener.debug(xml);
897 }
898 }
899
900
902 if (_logScriptBeforeListener.isDebugEnabled()) {
903 _logScriptBeforeListener.debug(script);
904 }
905
906 if (listener != null) {
907 script = listener.onScript(script);
908
909 if (_logScriptAfterListener.isDebugEnabled()) {
910 _logScriptAfterListener.debug(script);
911 }
912 }
913 }
914
915
917 String output = null;
918
919 if (Validator.isNull(langType)) {
920 output = LocalizationUtil.getLocalization(xml, languageId);
921 }
922 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
923 output = JournalVmUtil.transform(
924 tokens, viewMode, languageId, xml, script);
925 }
926 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_XSL)) {
927 output = JournalXslUtil.transform(
928 tokens, viewMode, languageId, xml, script);
929 }
930
931
933 for (int i = 0; i < listenersList.size(); i++) {
934 TransformerListener listener = listenersList.get(i);
935
936
938 if (_logOutputBeforeListener.isDebugEnabled()) {
939 _logOutputBeforeListener.debug(output);
940 }
941
942 output = listener.onOutput(output);
943
944 if (_logOutputAfterListener.isDebugEnabled()) {
945 _logOutputAfterListener.debug(output);
946 }
947 }
948
949 if (_logTransfromAfter.isDebugEnabled()) {
950 _logTransfromAfter.debug(output);
951 }
952
953 return output;
954 }
955
956 private static void _addElementOptions (
957 Element curContentElement, Element newContentElement) {
958
959 List<Element> newElementOptions = newContentElement.elements("option");
960
961 for (Element newElementOption : newElementOptions) {
962 Element curElementOption = SAXReaderUtil.createElement("option");
963
964 curElementOption.addCDATA(newElementOption.getText());
965
966 curContentElement.add(curElementOption);
967 }
968 }
969
970 private static Element _getElementByInstanceId(
971 Document document, String instanceId) {
972
973 XPath xPathSelector = SAXReaderUtil.createXPath(
974 "//dynamic-element[@instance-id='" + instanceId + "']");
975
976 List<Node> nodes = xPathSelector.selectNodes(document);
977
978 if (nodes.size() == 1) {
979 return (Element)nodes.get(0);
980 }
981 else {
982 return null;
983 }
984 }
985
986 private static void _mergeArticleContentDelete(
987 Element curParentElement, Document newDocument)
988 throws Exception {
989
990 List<Element> curElements = curParentElement.elements(
991 "dynamic-element");
992
993 for (int i = 0; i < curElements.size(); i++) {
994 Element curElement = curElements.get(i);
995
996 _mergeArticleContentDelete(curElement, newDocument);
997
998 String instanceId = curElement.attributeValue("instance-id");
999
1000 Element newElement = _getElementByInstanceId(
1001 newDocument, instanceId);
1002
1003 if (newElement == null) {
1004 curElement.detach();
1005
1006 String type = curElement.attributeValue("type");
1007
1008 if (type.equals("image")) {
1009 _mergeArticleContentDeleteImages(
1010 curElement.elements("dynamic-content"));
1011 }
1012 }
1013 }
1014 }
1015
1016 private static void _mergeArticleContentDeleteImages(List<Element> elements)
1017 throws Exception {
1018
1019 for (Element element : elements) {
1020 long articleImageId = GetterUtil.getLong(
1021 element.attributeValue("id"));
1022
1023 JournalArticleImageLocalServiceUtil.deleteArticleImage(
1024 articleImageId);
1025 }
1026 }
1027
1028 private static void _mergeArticleContentUpdate(
1029 Document curDocument, Element newParentElement,
1030 String defaultLocale)
1031 throws Exception {
1032
1033 List<Element> newElements = newParentElement.elements(
1034 "dynamic-element");
1035
1036 for (int i = 0; i < newElements.size(); i++) {
1037 Element newElement = newElements.get(i);
1038
1039 _mergeArticleContentUpdate(
1040 curDocument, newParentElement, newElement, i, defaultLocale);
1041 }
1042 }
1043
1044 private static void _mergeArticleContentUpdate(
1045 Document curDocument, Element newParentElement, Element newElement,
1046 int pos, String defaultLocale)
1047 throws Exception {
1048
1049 _mergeArticleContentUpdate(curDocument, newElement, defaultLocale);
1050
1051 String instanceId = newElement.attributeValue("instance-id");
1052
1053 Element curElement = _getElementByInstanceId(curDocument, instanceId);
1054
1055 if (curElement != null) {
1056 _mergeArticleContentUpdate(curElement, newElement, defaultLocale);
1057 }
1058 else {
1059 String parentInstanceId = newParentElement.attributeValue(
1060 "instance-id");
1061
1062 if (Validator.isNull(parentInstanceId)) {
1063 Element curRoot = curDocument.getRootElement();
1064
1065 List<Element> curRootElements = curRoot.elements();
1066
1067 curRootElements.add(pos, newElement.createCopy());
1068 }
1069 else {
1070 Element curParentElement = _getElementByInstanceId(
1071 curDocument, parentInstanceId);
1072
1073 if (curParentElement != null) {
1074 List<Element> curParentElements =
1075 curParentElement.elements();
1076
1077 curParentElements.add(pos, newElement.createCopy());
1078 }
1079 }
1080 }
1081 }
1082
1083 private static void _mergeArticleContentUpdate(
1084 Element curElement, Element newElement, String defaultLocale) {
1085
1086 Element newContentElement = newElement.elements(
1087 "dynamic-content").get(0);
1088
1089 String newLanguageId = newContentElement.attributeValue("language-id");
1090 String newValue = newContentElement.getText();
1091
1092 List<Element> curContentElements = curElement.elements(
1093 "dynamic-content");
1094
1095 if (Validator.isNull(newLanguageId)) {
1096 for (Element curContentElement : curContentElements) {
1097 curContentElement.detach();
1098 }
1099
1100 Element curContentElement = SAXReaderUtil.createElement(
1101 "dynamic-content");
1102
1103 if (newContentElement.element("option") != null) {
1104 _addElementOptions(curContentElement, newContentElement);
1105 }
1106 else {
1107 curContentElement.addCDATA(newValue);
1108 }
1109
1110 curElement.add(curContentElement);
1111 }
1112 else {
1113 boolean alreadyExists = false;
1114
1115 for (Element curContentElement : curContentElements) {
1116 String curLanguageId = curContentElement.attributeValue(
1117 "language-id");
1118
1119 if (newLanguageId.equals(curLanguageId)) {
1120 alreadyExists = true;
1121
1122 curContentElement.clearContent();
1123
1124 if (newContentElement.element("option") != null) {
1125 _addElementOptions(
1126 curContentElement, newContentElement);
1127 }
1128 else {
1129 curContentElement.addCDATA(newValue);
1130 }
1131
1132 break;
1133 }
1134 }
1135
1136 if (!alreadyExists) {
1137 Element curContentElement = curContentElements.get(0);
1138
1139 String curLanguageId = curContentElement.attributeValue(
1140 "language-id");
1141
1142 if (Validator.isNull(curLanguageId)) {
1143 curContentElement.detach();
1144 }
1145
1146 curElement.add(newContentElement.createCopy());
1147 }
1148 }
1149 }
1150
1151 private static void _populateTokens(
1152 Map<String, String> tokens, long groupId, String xmlRequest)
1153 throws Exception {
1154
1155 Document request = SAXReaderUtil.read(xmlRequest);
1156
1157 Element root = request.getRootElement();
1158
1159 Element themeDisplayEl = root.element("theme-display");
1160
1161 Layout layout = LayoutLocalServiceUtil.getLayout(
1162 GetterUtil.getLong(themeDisplayEl.elementText("plid")));
1163
1164 Group group = layout.getGroup();
1165
1166 LayoutSet layoutSet = layout.getLayoutSet();
1167
1168 String friendlyUrlCurrent = null;
1169
1170 if (layout.isPublicLayout()) {
1171 friendlyUrlCurrent = themeDisplayEl.elementText(
1172 "path-friendly-url-public");
1173 }
1174 else if (group.isUserGroup()) {
1175 friendlyUrlCurrent = themeDisplayEl.elementText(
1176 "path-friendly-url-private-user");
1177 }
1178 else {
1179 friendlyUrlCurrent = themeDisplayEl.elementText(
1180 "path-friendly-url-private-group");
1181 }
1182
1183 String layoutSetFriendlyUrl = StringPool.BLANK;
1184
1185 String virtualHost = layoutSet.getVirtualHost();
1186
1187 if (Validator.isNull(virtualHost) ||
1188 !virtualHost.equals(themeDisplayEl.elementText("server-name"))) {
1189
1190 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1191 }
1192
1193 tokens.put("cdn_host", themeDisplayEl.elementText("cdn-host"));
1194 tokens.put("company_id", themeDisplayEl.elementText("company-id"));
1195 tokens.put("friendly_url_current", friendlyUrlCurrent);
1196 tokens.put(
1197 "friendly_url_private_group",
1198 themeDisplayEl.elementText("path-friendly-url-private-group"));
1199 tokens.put(
1200 "friendly_url_private_user",
1201 themeDisplayEl.elementText("path-friendly-url-private-user"));
1202 tokens.put(
1203 "friendly_url_public",
1204 themeDisplayEl.elementText("path-friendly-url-public"));
1205 tokens.put("group_friendly_url", group.getFriendlyURL());
1206 tokens.put("group_id", String.valueOf(groupId));
1207 tokens.put("image_path", themeDisplayEl.elementText("path-image"));
1208 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1209 tokens.put("main_path", themeDisplayEl.elementText("path-main"));
1210 tokens.put("portal_ctx", themeDisplayEl.elementText("path-context"));
1211 tokens.put(
1212 "portal_url",
1213 HttpUtil.removeProtocol(themeDisplayEl.elementText("url-portal")));
1214 tokens.put(
1215 "protocol",
1216 HttpUtil.getProtocol(themeDisplayEl.elementText("url-portal")));
1217 tokens.put("root_path", themeDisplayEl.elementText("path-context"));
1218 tokens.put(
1219 "theme_image_path",
1220 themeDisplayEl.elementText("path-theme-images"));
1221
1222
1224 tokens.put(
1225 "friendly_url",
1226 themeDisplayEl.elementText("path-friendly-url-public"));
1227 tokens.put(
1228 "friendly_url_private",
1229 themeDisplayEl.elementText("path-friendly-url-private-group"));
1230 tokens.put(
1231 "page_url", themeDisplayEl.elementText("path-friendly-url-public"));
1232 }
1233
1234 private static void _populateTokens(
1235 Map<String, String> tokens, long groupId, ThemeDisplay themeDisplay) {
1236
1237 Layout layout = themeDisplay.getLayout();
1238
1239 Group group = layout.getGroup();
1240
1241 LayoutSet layoutSet = layout.getLayoutSet();
1242
1243 String friendlyUrlCurrent = null;
1244
1245 if (layout.isPublicLayout()) {
1246 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPublic();
1247 }
1248 else if (group.isUserGroup()) {
1249 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateUser();
1250 }
1251 else {
1252 friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateGroup();
1253 }
1254
1255 String layoutSetFriendlyUrl = StringPool.BLANK;
1256
1257 String virtualHost = layoutSet.getVirtualHost();
1258
1259 if (Validator.isNull(virtualHost) ||
1260 !virtualHost.equals(themeDisplay.getServerName())) {
1261
1262 layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1263 }
1264
1265 tokens.put("cdn_host", themeDisplay.getCDNHost());
1266 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
1267 tokens.put("friendly_url_current", friendlyUrlCurrent);
1268 tokens.put(
1269 "friendly_url_private_group",
1270 themeDisplay.getPathFriendlyURLPrivateGroup());
1271 tokens.put(
1272 "friendly_url_private_user",
1273 themeDisplay.getPathFriendlyURLPrivateUser());
1274 tokens.put(
1275 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
1276 tokens.put("group_friendly_url", group.getFriendlyURL());
1277 tokens.put("group_id", String.valueOf(groupId));
1278 tokens.put("image_path", themeDisplay.getPathImage());
1279 tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1280 tokens.put("main_path", themeDisplay.getPathMain());
1281 tokens.put("portal_ctx", themeDisplay.getPathContext());
1282 tokens.put(
1283 "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
1284 tokens.put(
1285 "protocol", HttpUtil.getProtocol(themeDisplay.getURLPortal()));
1286 tokens.put("root_path", themeDisplay.getPathContext());
1287 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
1288
1289
1291 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
1292 tokens.put(
1293 "friendly_url_private",
1294 themeDisplay.getPathFriendlyURLPrivateGroup());
1295 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
1296 }
1297
1298 private static void _removeOldContent(
1299 Stack<String> path, Element contentEl, Document xsdDoc)
1300 throws SystemException {
1301
1302 String elPath = "";
1303
1304 for (int i = 0; i < path.size(); i++) {
1305 elPath += "/" + path.elementAt(i);
1306 }
1307
1308 for (int i = 0; i < contentEl.nodeCount(); i++) {
1309 Node contentNode = contentEl.node(i);
1310
1311 if (contentNode instanceof Element) {
1312 _removeOldContent(path, (Element)contentNode, xsdDoc, elPath);
1313 }
1314 }
1315 }
1316
1317 private static void _removeOldContent(
1318 Stack<String> path, Element contentEl, Document xsdDoc,
1319 String elPath)
1320 throws SystemException {
1321
1322 String name = contentEl.attributeValue("name");
1323
1324 if (Validator.isNull(name)) {
1325 return;
1326 }
1327
1328 String localPath = "dynamic-element[@name='" + name + "']";
1329
1330 String fullPath = elPath + "/" + localPath;
1331
1332 XPath xPathSelector = SAXReaderUtil.createXPath(fullPath);
1333
1334 List<Node> curNodes = xPathSelector.selectNodes(xsdDoc);
1335
1336 if (curNodes.size() == 0) {
1337 contentEl.detach();
1338 }
1339
1340 path.push(localPath);
1341
1342 _removeOldContent(path, contentEl, xsdDoc);
1343
1344 path.pop();
1345 }
1346
1347 private static Log _log = LogFactoryUtil.getLog(JournalUtil.class);
1348
1349 private static Log _logOutputAfterListener = LogFactoryUtil.getLog(
1350 JournalUtil.class.getName() + ".OutputAfterListener");
1351
1352 private static Log _logOutputBeforeListener = LogFactoryUtil.getLog(
1353 JournalUtil.class.getName() + ".OutputBeforeListener");
1354
1355 private static Log _logScriptAfterListener = LogFactoryUtil.getLog(
1356 JournalUtil.class.getName() + ".ScriptAfterListener");
1357
1358 private static Log _logScriptBeforeListener = LogFactoryUtil.getLog(
1359 JournalUtil.class.getName() + ".ScriptBeforeListener");
1360
1361 private static Log _logTransfromAfter = LogFactoryUtil.getLog(
1362 JournalUtil.class.getName() + ".TransformAfter");
1363
1364 private static Log _logTransformBefore = LogFactoryUtil.getLog(
1365 JournalUtil.class.getName() + ".BeforeTransform");
1366
1367 private static Log _logTokens = LogFactoryUtil.getLog(
1368 JournalUtil.class.getName() + ".Tokens");
1369
1370 private static Log _logXmlAfterListener = LogFactoryUtil.getLog(
1371 JournalUtil.class.getName() + ".XmlAfterListener");
1372
1373 private static Log _logXmlBeforeListener = LogFactoryUtil.getLog(
1374 JournalUtil.class.getName() + ".XmlBeforeListener");
1375
1376}