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.model.Contact;
37 import com.liferay.portal.model.User;
38 import com.liferay.portal.service.ImageLocalServiceUtil;
39 import com.liferay.portal.service.UserLocalServiceUtil;
40 import com.liferay.portal.theme.ThemeDisplay;
41 import com.liferay.portal.util.ContentUtil;
42 import com.liferay.portal.util.PropsKeys;
43 import com.liferay.portal.util.PropsUtil;
44 import com.liferay.portal.util.WebKeys;
45 import com.liferay.portlet.journal.model.JournalArticle;
46 import com.liferay.portlet.journal.model.JournalStructure;
47 import com.liferay.portlet.journal.model.JournalTemplate;
48 import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
49 import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
50 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
51 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
52 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
53 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
54 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
55 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
56 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
57 import com.liferay.util.FiniteUniqueStack;
58 import com.liferay.util.xml.XMLFormatter;
59
60 import java.io.IOException;
61 import java.io.StringReader;
62
63 import java.util.ArrayList;
64 import java.util.Date;
65 import java.util.HashMap;
66 import java.util.Iterator;
67 import java.util.List;
68 import java.util.Map;
69 import java.util.Stack;
70
71 import javax.portlet.PortletPreferences;
72 import javax.portlet.PortletRequest;
73 import javax.portlet.PortletSession;
74
75 import org.apache.commons.logging.Log;
76 import org.apache.commons.logging.LogFactory;
77
78 import org.dom4j.Document;
79 import org.dom4j.DocumentException;
80 import org.dom4j.DocumentFactory;
81 import org.dom4j.DocumentHelper;
82 import org.dom4j.Element;
83 import org.dom4j.Node;
84 import org.dom4j.XPath;
85 import org.dom4j.io.SAXReader;
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 DocumentFactory docFactory = DocumentFactory.getInstance();
149
150 Element dynamicEl = docFactory.createElement("dynamic-element");
151
152 dynamicEl.add(docFactory.createAttribute(dynamicEl, "name", name));
153 dynamicEl.add(
154 docFactory.createAttribute(dynamicEl, "type", "text"));
155
156 Element dynamicContent =
157 docFactory.createElement("dynamic-content");
158
159 dynamicContent.setText(value);
161
162 dynamicEl.add(dynamicContent);
163
164 root.add(dynamicEl);
165 }
166
167
169 tokens.put(
170 StringUtil.replace(name, StringPool.DASH, StringPool.UNDERLINE),
171 value);
172 }
173
174 public static void addAllReservedEls(
175 Element root, Map<String, String> tokens, JournalArticle article) {
176
177 JournalUtil.addReservedEl(
178 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_ID,
179 article.getArticleId());
180
181 JournalUtil.addReservedEl(
182 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_VERSION,
183 article.getVersion());
184
185 JournalUtil.addReservedEl(
186 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TITLE,
187 article.getTitle());
188
189 JournalUtil.addReservedEl(
190 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_DESCRIPTION,
191 article.getDescription());
192
193 JournalUtil.addReservedEl(
194 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TYPE,
195 article.getType());
196
197 JournalUtil.addReservedEl(
198 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_CREATE_DATE,
199 article.getCreateDate());
200
201 JournalUtil.addReservedEl(
202 root, tokens,
203 JournalStructureImpl.RESERVED_ARTICLE_MODIFIED_DATE,
204 article.getModifiedDate());
205
206 if (article.getDisplayDate() != null) {
207 JournalUtil.addReservedEl(
208 root, tokens,
209 JournalStructureImpl.RESERVED_ARTICLE_DISPLAY_DATE,
210 article.getDisplayDate());
211 }
212
213 JournalUtil.addReservedEl(
214 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_SMALL_IMAGE_URL,
215 article.getSmallImageURL());
216
217 JournalUtil.addReservedEl(
218 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_ID,
219 String.valueOf(article.getUserId()));
220
221 String userName = StringPool.BLANK;
222 String userEmailAddress = StringPool.BLANK;
223 String userComments = StringPool.BLANK;
224 String userJobTitle = StringPool.BLANK;
225
226 User user = null;
227
228 try {
229 user = UserLocalServiceUtil.getUserById(article.getUserId());
230
231 userName = user.getFullName();
232 userEmailAddress = user.getEmailAddress();
233 userComments = user.getComments();
234
235 Contact contact = user.getContact();
236
237 if (contact != null) {
238 userJobTitle = contact.getJobTitle();
239 }
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 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 XMLFormatter.toString(doc, 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 ArticleModifiedDateComparator(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 Map<String, String> tokens = new HashMap<String, String>();
641
642 if (themeDisplay == null) {
643 return tokens;
644 }
645
646 tokens.put("cdn_host", themeDisplay.getCDNHost());
647 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
648 tokens.put("group_id", String.valueOf(groupId));
649 tokens.put("cms_url", themeDisplay.getPathContext() + "/cms/servlet");
650 tokens.put("image_path", themeDisplay.getPathImage());
651 tokens.put(
652 "friendly_url_private_group",
653 themeDisplay.getPathFriendlyURLPrivateGroup());
654 tokens.put(
655 "friendly_url_private_user",
656 themeDisplay.getPathFriendlyURLPrivateUser());
657 tokens.put(
658 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
659 tokens.put("main_path", themeDisplay.getPathMain());
660 tokens.put("portal_ctx", themeDisplay.getPathContext());
661 tokens.put(
662 "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
663 tokens.put("root_path", themeDisplay.getPathContext());
664 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
665
666
668 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
669 tokens.put(
670 "friendly_url_private",
671 themeDisplay.getPathFriendlyURLPrivateGroup());
672 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
673
674 return tokens;
675 }
676
677 public static String mergeLocaleContent(
678 String curContent, String newContent, String xsd) {
679
680 try {
681 SAXReader reader = new SAXReader();
682
683 Document curContentDoc = reader.read(new StringReader(curContent));
684 Document newContentDoc = reader.read(new StringReader(newContent));
685 Document xsdDoc = reader.read(new StringReader(xsd));
686
687 Element curContentRoot = curContentDoc.getRootElement();
688 Element newContentRoot = newContentDoc.getRootElement();
689 Element xsdRoot = xsdDoc.getRootElement();
690
691 curContentRoot.addAttribute(
692 "default-locale",
693 newContentRoot.attributeValue("default-locale"));
694 curContentRoot.addAttribute(
695 "available-locales",
696 newContentRoot.attributeValue("available-locales"));
697
698 Stack<String> path = new Stack<String>();
699
700 path.push(xsdRoot.getName());
701
702 _mergeLocaleContent(
703 path, curContentDoc, newContentDoc, xsdRoot,
704 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
705
706 curContent = formatXML(curContentDoc);
707 }
708 catch (Exception e) {
709 _log.error(e);
710 }
711
712 return curContent;
713 }
714
715 public static String removeArticleLocale(
716 String content, String languageId) {
717
718 try {
719 SAXReader reader = new SAXReader();
720
721 Document doc = reader.read(new StringReader(content));
722
723 Element root = doc.getRootElement();
724
725 String availableLocales = root.attributeValue("available-locales");
726
727 if (availableLocales == null) {
728 return content;
729 }
730
731 availableLocales = StringUtil.remove(availableLocales, languageId);
732
733 if (availableLocales.endsWith(",")) {
734 availableLocales = availableLocales.substring(
735 0, availableLocales.length() - 1);
736 }
737
738 root.addAttribute("available-locales", availableLocales);
739
740 removeArticleLocale(root, languageId);
741
742 content = formatXML(doc);
743 }
744 catch (Exception e) {
745 _log.error(e);
746 }
747
748 return content;
749 }
750
751 public static void removeArticleLocale(Element el, String languageId)
752 throws PortalException, SystemException {
753
754 for (Element dynamicEl :
755 (List<Element>)el.elements("dynamic-element")) {
756
757 for (Element dynamicContentEl :
758 (List<Element>)dynamicEl.elements("dynamic-content")) {
759
760 String curLanguageId = GetterUtil.getString(
761 dynamicContentEl.attributeValue("language-id"));
762
763 if (curLanguageId.equals(languageId)) {
764 long id = GetterUtil.getLong(
765 dynamicContentEl.attributeValue("id"));
766
767 if (id > 0) {
768 ImageLocalServiceUtil.deleteImage(id);
769 }
770
771 dynamicContentEl.detach();
772 }
773 }
774
775 removeArticleLocale(dynamicEl, languageId);
776 }
777 }
778
779 public static String removeOldContent(String content, String xsd) {
780 try {
781 SAXReader reader = new SAXReader();
782
783 Document contentDoc = reader.read(new StringReader(content));
784 Document xsdDoc = reader.read(new StringReader(xsd));
785
786 Element contentRoot = contentDoc.getRootElement();
787
788 Stack<String> path = new Stack<String>();
789
790 path.push(contentRoot.getName());
791
792 _removeOldContent(path, contentRoot, xsdDoc);
793
794 content = formatXML(contentDoc);
795 }
796 catch (Exception e) {
797 _log.error(e);
798 }
799
800 return content;
801 }
802
803 public static void removeRecentArticle(
804 PortletRequest portletRequest, String articleId) {
805
806 Stack<JournalArticle> stack = getRecentArticles(portletRequest);
807
808 Iterator<JournalArticle> itr = stack.iterator();
809
810 while (itr.hasNext()) {
811 JournalArticle journalArticle = itr.next();
812
813 if (journalArticle.getArticleId().equals(articleId)) {
814 itr.remove();
815
816 break;
817 }
818 }
819 }
820
821 public static void removeRecentStructure(
822 PortletRequest portletRequest, String structureId) {
823
824 Stack<JournalStructure> stack = getRecentStructures(portletRequest);
825
826 Iterator<JournalStructure> itr = stack.iterator();
827
828 while (itr.hasNext()) {
829 JournalStructure journalStructure = itr.next();
830
831 if (journalStructure.getStructureId().equals(structureId)) {
832 itr.remove();
833
834 break;
835 }
836 }
837 }
838
839 public static void removeRecentTemplate(
840 PortletRequest portletRequest, String templateId) {
841
842 Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
843
844 Iterator<JournalTemplate> itr = stack.iterator();
845
846 while (itr.hasNext()) {
847 JournalTemplate journalTemplate = itr.next();
848
849 if (journalTemplate.getTemplateId().equals(templateId)) {
850 itr.remove();
851
852 break;
853 }
854 }
855 }
856
857 public static String transform(
858 Map<String, String> tokens, String languageId, String xml,
859 String script, String langType)
860 throws Exception {
861
862
864 if (_log.isDebugEnabled()) {
865 _log.debug("Language " + languageId);
866 }
867
868 if (_logTokens.isDebugEnabled()) {
869 String tokensString = PropertiesUtil.list(tokens);
870
871 _logTokens.debug(tokensString);
872 }
873
874 if (_logTransformBefore.isDebugEnabled()) {
875 _logTransformBefore.debug(xml);
876 }
877
878 List<TransformerListener> listenersList =
879 new ArrayList<TransformerListener>();
880
881 String[] listeners = PropsUtil.getArray(
882 PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
883
884 for (int i = 0; i < listeners.length; i++) {
885 TransformerListener listener = null;
886
887 try {
888 if (_log.isDebugEnabled()) {
889 _log.debug("Instantiate listener " + listeners[i]);
890 }
891
892 boolean templateDriven = Validator.isNotNull(langType);
893
894 listener = (TransformerListener)Class.forName(
895 listeners[i]).newInstance();
896
897 listener.setTemplateDriven(templateDriven);
898 listener.setLanguageId(languageId);
899 listener.setTokens(tokens);
900
901 listenersList.add(listener);
902 }
903 catch (Exception e) {
904 _log.error(e, e);
905 }
906
907
909 if (_logXmlBeforeListener.isDebugEnabled()) {
910 _logXmlBeforeListener.debug(xml);
911 }
912
913 if (listener != null) {
914 xml = listener.onXml(xml);
915
916 if (_logXmlAfterListener.isDebugEnabled()) {
917 _logXmlAfterListener.debug(xml);
918 }
919 }
920
921
923 if (_logScriptBeforeListener.isDebugEnabled()) {
924 _logScriptBeforeListener.debug(script);
925 }
926
927 if (listener != null) {
928 script = listener.onScript(script);
929
930 if (_logScriptAfterListener.isDebugEnabled()) {
931 _logScriptAfterListener.debug(script);
932 }
933 }
934 }
935
936
938 String output = null;
939
940 if (Validator.isNull(langType)) {
941 output = xml;
942 }
943 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
944 output = JournalVmUtil.transform(tokens, languageId, xml, script);
945 }
946 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_XSL)) {
947 output = JournalXslUtil.transform(tokens, languageId, xml, script);
948 }
949
950
952 for (int i = 0; i < listenersList.size(); i++) {
953 TransformerListener listener = listenersList.get(i);
954
955
957 if (_logOutputBeforeListener.isDebugEnabled()) {
958 _logOutputBeforeListener.debug(output);
959 }
960
961 output = listener.onOutput(output);
962
963 if (_logOutputAfterListener.isDebugEnabled()) {
964 _logOutputAfterListener.debug(output);
965 }
966 }
967
968 if (_logTransfromAfter.isDebugEnabled()) {
969 _logTransfromAfter.debug(output);
970 }
971
972 return output;
973 }
974
975 private static void _mergeLocaleContent(
976 Stack<String> path, Document curDoc, Document newDoc, Element xsdEl,
977 String defaultLocale)
978 throws PortalException, SystemException {
979
980 String elPath = "";
981
982 for (int i = 0; i < path.size(); i++) {
983 elPath += "/" + path.elementAt(i);
984 }
985
986 for (int i = 0; i < xsdEl.nodeCount(); i++) {
987 Node xsdNode = xsdEl.node(i);
988
989 if ((xsdNode instanceof Element) &&
990 (xsdNode.getName().equals("dynamic-element"))) {
991
992 _mergeLocaleContent(
993 path, curDoc, newDoc, (Element)xsdNode, defaultLocale,
994 elPath);
995 }
996 }
997 }
998
999 private static void _mergeLocaleContent(
1000 Stack<String> path, Document curDoc, Document newDoc, Element xsdEl,
1001 String defaultLocale, String elPath)
1002 throws PortalException, SystemException {
1003
1004 String name = xsdEl.attributeValue("name");
1005
1006 String localPath = "dynamic-element[@name='" + name + "']";
1007
1008 String fullPath = elPath + "/" + localPath;
1009
1010 XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1011
1012 List<Element> curElements = xPathSelector.selectNodes(curDoc);
1013
1014 Element newEl = (Element)xPathSelector.selectNodes(newDoc).get(0);
1015
1016 if (curElements.size() > 0) {
1017 Element curEl = curElements.get(0);
1018
1019 List<Element> curDynamicContents = curEl.elements(
1020 "dynamic-content");
1021
1022 Element newContentEl = newEl.element("dynamic-content");
1023
1024 String newContentLanguageId = newContentEl.attributeValue(
1025 "language-id", StringPool.BLANK);
1026
1027 if (newContentLanguageId.equals(StringPool.BLANK)) {
1028 for (int k = curDynamicContents.size() - 1; k >= 0 ; k--) {
1029 Element curContentEl = curDynamicContents.get(k);
1030
1031 String curContentLanguageId = curContentEl.attributeValue(
1032 "language-id", StringPool.BLANK);
1033
1034 if ((curEl.attributeValue("type").equals("image")) &&
1035 (!curContentLanguageId.equals(defaultLocale) &&
1036 !curContentLanguageId.equals(StringPool.BLANK))) {
1037
1038 long id = GetterUtil.getLong(
1039 curContentEl.attributeValue("id"));
1040
1041 ImageLocalServiceUtil.deleteImage(id);
1042 }
1043
1044 curContentEl.detach();
1045 }
1046
1047 curEl.content().add(newContentEl.createCopy());
1048 }
1049 else {
1050 boolean match = false;
1051
1052 for (int k = curDynamicContents.size() - 1; k >= 0 ; k--) {
1053 Element curContentEl = curDynamicContents.get(k);
1054
1055 String curContentLanguageId = curContentEl.attributeValue(
1056 "language-id", StringPool.BLANK);
1057
1058 if ((newContentLanguageId.equals(curContentLanguageId)) ||
1059 (newContentLanguageId.equals(defaultLocale) &&
1060 curContentLanguageId.equals(StringPool.BLANK))) {
1061
1062 curContentEl.detach();
1063
1064 curEl.content().add(k, newContentEl.createCopy());
1065
1066 match = true;
1067 }
1068
1069 if (curContentLanguageId.equals(StringPool.BLANK)) {
1070 curContentEl.addAttribute("language-id", defaultLocale);
1071 }
1072 }
1073
1074 if (!match) {
1075 curEl.content().add(newContentEl.createCopy());
1076 }
1077 }
1078 }
1079 else {
1080 xPathSelector = DocumentHelper.createXPath(elPath);
1081
1082 Element parentEl =
1083 (Element)xPathSelector.selectNodes(curDoc).get(0);
1084
1085 parentEl.content().add(newEl.createCopy());
1086 }
1087
1088 String type = xsdEl.attributeValue("type", StringPool.BLANK);
1089
1090 if (!type.equals("list") && !type.equals("multi-list")) {
1091 path.push(localPath);
1092
1093 _mergeLocaleContent(path, curDoc, newDoc, xsdEl, defaultLocale);
1094
1095 path.pop();
1096 }
1097 }
1098
1099 private static void _removeOldContent(
1100 Stack<String> path, Element contentEl, Document xsdDoc)
1101 throws SystemException {
1102
1103 String elPath = "";
1104
1105 for (int i = 0; i < path.size(); i++) {
1106 elPath += "/" + path.elementAt(i);
1107 }
1108
1109 for (int i = 0; i < contentEl.nodeCount(); i++) {
1110 Node contentNode = contentEl.node(i);
1111
1112 if (contentNode instanceof Element) {
1113 _removeOldContent(path, (Element)contentNode, xsdDoc, elPath);
1114 }
1115 }
1116 }
1117
1118 private static void _removeOldContent(
1119 Stack<String> path, Element contentEl, Document xsdDoc,
1120 String elPath)
1121 throws SystemException {
1122
1123 String name = contentEl.attributeValue("name");
1124
1125 if (Validator.isNull(name)) {
1126 return;
1127 }
1128
1129 String localPath = "dynamic-element[@name='" + name + "']";
1130
1131 String fullPath = elPath + "/" + localPath;
1132
1133 XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1134
1135 List<Element> curElements = xPathSelector.selectNodes(xsdDoc);
1136
1137 if (curElements.size() == 0) {
1138 contentEl.detach();
1139 }
1140
1141 path.push(localPath);
1142
1143 _removeOldContent(path, contentEl, xsdDoc);
1144
1145 path.pop();
1146 }
1147
1148 private static Log _log = LogFactory.getLog(JournalUtil.class);
1149
1150 private static Log _logOutputAfterListener = LogFactory.getLog(
1151 JournalUtil.class.getName() + ".OutputAfterListener");
1152
1153 private static Log _logOutputBeforeListener = LogFactory.getLog(
1154 JournalUtil.class.getName() + ".OutputBeforeListener");
1155
1156 private static Log _logScriptAfterListener = LogFactory.getLog(
1157 JournalUtil.class.getName() + ".ScriptAfterListener");
1158
1159 private static Log _logScriptBeforeListener = LogFactory.getLog(
1160 JournalUtil.class.getName() + ".ScriptBeforeListener");
1161
1162 private static Log _logTransfromAfter = LogFactory.getLog(
1163 JournalUtil.class.getName() + ".TransformAfter");
1164
1165 private static Log _logTransformBefore = LogFactory.getLog(
1166 JournalUtil.class.getName() + ".BeforeTransform");
1167
1168 private static Log _logTokens = LogFactory.getLog(
1169 JournalUtil.class.getName() + ".Tokens");
1170
1171 private static Log _logXmlAfterListener = LogFactory.getLog(
1172 JournalUtil.class.getName() + ".XmlAfterListener");
1173
1174 private static Log _logXmlBeforeListener = LogFactory.getLog(
1175 JournalUtil.class.getName() + ".XmlBeforeListener");
1176
1177}