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