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.Validator;
35 import com.liferay.portal.model.Contact;
36 import com.liferay.portal.model.User;
37 import com.liferay.portal.service.UserLocalServiceUtil;
38 import com.liferay.portal.service.impl.ImageLocalUtil;
39 import com.liferay.portal.theme.ThemeDisplay;
40 import com.liferay.portal.util.ContentUtil;
41 import com.liferay.portal.util.PropsUtil;
42 import com.liferay.portal.util.WebKeys;
43 import com.liferay.portlet.journal.TransformException;
44 import com.liferay.portlet.journal.model.JournalArticle;
45 import com.liferay.portlet.journal.model.JournalStructure;
46 import com.liferay.portlet.journal.model.JournalTemplate;
47 import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
48 import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
49 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
50 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
51 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
52 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
53 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
54 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
55 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
56 import com.liferay.util.FiniteUniqueStack;
57 import com.liferay.util.Time;
58 import com.liferay.util.xml.XMLFormatter;
59
60 import java.io.IOException;
61 import java.io.StringReader;
62 import java.io.UnsupportedEncodingException;
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 req, JournalArticle article) {
103
104 if (article != null) {
105 Stack<JournalArticle> stack = getRecentArticles(req);
106
107 stack.push(article);
108 }
109 }
110
111 public static void addRecentStructure(
112 PortletRequest req, JournalStructure structure) {
113
114 if (structure != null) {
115 Stack<JournalStructure> stack = getRecentStructures(req);
116
117 stack.push(structure);
118 }
119 }
120
121 public static void addRecentTemplate(
122 PortletRequest req, JournalTemplate template) {
123
124 if (template != null) {
125 Stack<JournalTemplate> stack = getRecentTemplates(req);
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)
288 throws DocumentException, IOException {
289
290 return XMLFormatter.toString(doc, XML_INDENT);
291 }
292
293 public static OrderByComparator getArticleOrderByComparator(
294 String orderByCol, String orderByType) {
295
296 boolean orderByAsc = false;
297
298 if (orderByType.equals("asc")) {
299 orderByAsc = true;
300 }
301
302 OrderByComparator orderByComparator = null;
303
304 if (orderByCol.equals("create-date")) {
305 orderByComparator = new ArticleCreateDateComparator(orderByAsc);
306 }
307 else if (orderByCol.equals("display-date")) {
308 orderByComparator = new ArticleDisplayDateComparator(orderByAsc);
309 }
310 else if (orderByCol.equals("id")) {
311 orderByComparator = new ArticleIDComparator(orderByAsc);
312 }
313 else if (orderByCol.equals("modified-date")) {
314 orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
315 }
316 else if (orderByCol.equals("review-date")) {
317 orderByComparator = new ArticleReviewDateComparator(orderByAsc);
318 }
319 else if (orderByCol.equals("title")) {
320 orderByComparator = new ArticleTitleComparator(orderByAsc);
321 }
322 else if (orderByCol.equals("version")) {
323 orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
324 }
325
326 return orderByComparator;
327 }
328
329 public static String getEmailFromAddress(PortletPreferences prefs) {
330 String emailFromAddress = PropsUtil.get(
331 PropsUtil.JOURNAL_EMAIL_FROM_ADDRESS);
332
333 return prefs.getValue("email-from-address", emailFromAddress);
334 }
335
336 public static String getEmailFromName(PortletPreferences prefs) {
337 String emailFromName = PropsUtil.get(
338 PropsUtil.JOURNAL_EMAIL_FROM_NAME);
339
340 return prefs.getValue("email-from-name", emailFromName);
341 }
342
343 public static boolean getEmailArticleApprovalDeniedEnabled(
344 PortletPreferences prefs) {
345
346 String emailArticleApprovalDeniedEnabled = prefs.getValue(
347 "email-article-approval-denied-enabled", StringPool.BLANK);
348
349 if (Validator.isNotNull(emailArticleApprovalDeniedEnabled)) {
350 return GetterUtil.getBoolean(emailArticleApprovalDeniedEnabled);
351 }
352 else {
353 return GetterUtil.getBoolean(PropsUtil.get(
354 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_ENABLED));
355 }
356 }
357
358 public static String getEmailArticleApprovalDeniedBody(
359 PortletPreferences prefs)
360 throws IOException {
361
362 String emailArticleApprovalDeniedBody = prefs.getValue(
363 "email-article-approval-denied-body", StringPool.BLANK);
364
365 if (Validator.isNotNull(emailArticleApprovalDeniedBody)) {
366 return emailArticleApprovalDeniedBody;
367 }
368 else {
369 return ContentUtil.get(PropsUtil.get(
370 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_BODY));
371 }
372 }
373
374 public static String getEmailArticleApprovalDeniedSubject(
375 PortletPreferences prefs)
376 throws IOException {
377
378 String emailArticleApprovalDeniedSubject = prefs.getValue(
379 "email-article-approval-denied-subject", StringPool.BLANK);
380
381 if (Validator.isNotNull(emailArticleApprovalDeniedSubject)) {
382 return emailArticleApprovalDeniedSubject;
383 }
384 else {
385 return ContentUtil.get(PropsUtil.get(
386 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_SUBJECT));
387 }
388 }
389
390 public static boolean getEmailArticleApprovalGrantedEnabled(
391 PortletPreferences prefs) {
392
393 String emailArticleApprovalGrantedEnabled = prefs.getValue(
394 "email-article-approval-granted-enabled", StringPool.BLANK);
395
396 if (Validator.isNotNull(emailArticleApprovalGrantedEnabled)) {
397 return GetterUtil.getBoolean(emailArticleApprovalGrantedEnabled);
398 }
399 else {
400 return GetterUtil.getBoolean(PropsUtil.get(
401 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_ENABLED));
402 }
403 }
404
405 public static String getEmailArticleApprovalGrantedBody(
406 PortletPreferences prefs)
407 throws IOException {
408
409 String emailArticleApprovalGrantedBody = prefs.getValue(
410 "email-article-approval-granted-body", StringPool.BLANK);
411
412 if (Validator.isNotNull(emailArticleApprovalGrantedBody)) {
413 return emailArticleApprovalGrantedBody;
414 }
415 else {
416 return ContentUtil.get(PropsUtil.get(
417 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_BODY));
418 }
419 }
420
421 public static String getEmailArticleApprovalGrantedSubject(
422 PortletPreferences prefs)
423 throws IOException {
424
425 String emailArticleApprovalGrantedSubject = prefs.getValue(
426 "email-article-approval-granted-subject", StringPool.BLANK);
427
428 if (Validator.isNotNull(emailArticleApprovalGrantedSubject)) {
429 return emailArticleApprovalGrantedSubject;
430 }
431 else {
432 return ContentUtil.get(PropsUtil.get(
433 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_SUBJECT));
434 }
435 }
436
437 public static boolean getEmailArticleApprovalRequestedEnabled(
438 PortletPreferences prefs) {
439
440 String emailArticleApprovalRequestedEnabled = prefs.getValue(
441 "email-article-approval-requested-enabled", StringPool.BLANK);
442
443 if (Validator.isNotNull(emailArticleApprovalRequestedEnabled)) {
444 return GetterUtil.getBoolean(emailArticleApprovalRequestedEnabled);
445 }
446 else {
447 return GetterUtil.getBoolean(PropsUtil.get(
448 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_ENABLED));
449 }
450 }
451
452 public static String getEmailArticleApprovalRequestedBody(
453 PortletPreferences prefs)
454 throws IOException {
455
456 String emailArticleApprovalRequestedBody = prefs.getValue(
457 "email-article-approval-requested-body", StringPool.BLANK);
458
459 if (Validator.isNotNull(emailArticleApprovalRequestedBody)) {
460 return emailArticleApprovalRequestedBody;
461 }
462 else {
463 return ContentUtil.get(PropsUtil.get(
464 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_BODY));
465 }
466 }
467
468 public static String getEmailArticleApprovalRequestedSubject(
469 PortletPreferences prefs)
470 throws IOException {
471
472 String emailArticleApprovalRequestedSubject = prefs.getValue(
473 "email-article-approval-requested-subject", StringPool.BLANK);
474
475 if (Validator.isNotNull(emailArticleApprovalRequestedSubject)) {
476 return emailArticleApprovalRequestedSubject;
477 }
478 else {
479 return ContentUtil.get(PropsUtil.get(
480 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_SUBJECT));
481 }
482 }
483
484 public static boolean getEmailArticleReviewEnabled(
485 PortletPreferences prefs) {
486
487 String emailArticleReviewEnabled = prefs.getValue(
488 "email-article-review-enabled", StringPool.BLANK);
489
490 if (Validator.isNotNull(emailArticleReviewEnabled)) {
491 return GetterUtil.getBoolean(emailArticleReviewEnabled);
492 }
493 else {
494 return GetterUtil.getBoolean(PropsUtil.get(
495 PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_ENABLED));
496 }
497 }
498
499 public static String getEmailArticleReviewBody(PortletPreferences prefs)
500 throws IOException {
501
502 String emailArticleReviewBody = prefs.getValue(
503 "email-article-review-body", StringPool.BLANK);
504
505 if (Validator.isNotNull(emailArticleReviewBody)) {
506 return emailArticleReviewBody;
507 }
508 else {
509 return ContentUtil.get(PropsUtil.get(
510 PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_BODY));
511 }
512 }
513
514 public static String getEmailArticleReviewSubject(PortletPreferences prefs)
515 throws IOException {
516
517 String emailArticleReviewSubject = prefs.getValue(
518 "email-article-review-subject", StringPool.BLANK);
519
520 if (Validator.isNotNull(emailArticleReviewSubject)) {
521 return emailArticleReviewSubject;
522 }
523 else {
524 return ContentUtil.get(PropsUtil.get(
525 PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_SUBJECT));
526 }
527 }
528
529 public static Stack<JournalArticle> getRecentArticles(PortletRequest req) {
530 PortletSession ses = req.getPortletSession();
531
532 Stack<JournalArticle> recentArticles =
533 (Stack<JournalArticle>)ses.getAttribute(
534 WebKeys.JOURNAL_RECENT_ARTICLES);
535
536 if (recentArticles == null) {
537 recentArticles = new FiniteUniqueStack<JournalArticle>(
538 MAX_STACK_SIZE);
539
540 ses.setAttribute(WebKeys.JOURNAL_RECENT_ARTICLES, recentArticles);
541 }
542
543 return recentArticles;
544 }
545
546 public static Stack<JournalStructure> getRecentStructures(
547 PortletRequest req) {
548
549 PortletSession ses = req.getPortletSession();
550
551 Stack<JournalStructure> recentStructures =
552 (Stack<JournalStructure>)ses.getAttribute(
553 WebKeys.JOURNAL_RECENT_STRUCTURES);
554
555 if (recentStructures == null) {
556 recentStructures = new FiniteUniqueStack<JournalStructure>(
557 MAX_STACK_SIZE);
558
559 ses.setAttribute(
560 WebKeys.JOURNAL_RECENT_STRUCTURES, recentStructures);
561 }
562
563 return recentStructures;
564 }
565
566 public static Stack<JournalTemplate> getRecentTemplates(
567 PortletRequest req) {
568
569 PortletSession ses = req.getPortletSession();
570
571 Stack<JournalTemplate> recentTemplates =
572 (Stack<JournalTemplate>)ses.getAttribute(
573 WebKeys.JOURNAL_RECENT_TEMPLATES);
574
575 if (recentTemplates == null) {
576 recentTemplates = new FiniteUniqueStack<JournalTemplate>(
577 MAX_STACK_SIZE);
578
579 ses.setAttribute(WebKeys.JOURNAL_RECENT_TEMPLATES, recentTemplates);
580 }
581
582 return recentTemplates;
583 }
584
585 public static String getTemplateScript(
586 long groupId, String templateId, Map<String, String> tokens,
587 String languageId)
588 throws PortalException, SystemException {
589
590 return getTemplateScript(groupId, templateId, tokens, languageId, true);
591 }
592
593 public static String getTemplateScript(
594 long groupId, String templateId, Map<String, String> tokens,
595 String languageId, boolean transform)
596 throws PortalException, SystemException {
597
598 JournalTemplate template = JournalTemplateLocalServiceUtil.getTemplate(
599 groupId, templateId);
600
601 return getTemplateScript(template, tokens, languageId, transform);
602 }
603
604 public static String getTemplateScript(
605 JournalTemplate template, Map<String, String> tokens,
606 String languageId, boolean transform)
607 throws PortalException, SystemException {
608
609 String script = template.getXsl();
610
611 if (transform) {
612
613
615 String[] listeners =
616 PropsUtil.getArray(PropsUtil.JOURNAL_TRANSFORMER_LISTENER);
617
618 for (int i = 0; i < listeners.length; i++) {
619 TransformerListener listener = null;
620
621 try {
622 listener =
623 (TransformerListener)Class.forName(
624 listeners[i]).newInstance();
625
626 listener.setTemplateDriven(true);
627 listener.setLanguageId(languageId);
628 listener.setTokens(tokens);
629 }
630 catch (Exception e) {
631 e.printStackTrace();
632 }
633
634
636 if (listener != null) {
637 script = listener.onScript(script);
638 }
639 }
640 }
641
642 return script;
643 }
644
645 public static Map<String, String> getTokens(
646 long groupId, ThemeDisplay themeDisplay) {
647
648 Map<String, String> tokens = new HashMap<String, String>();
649
650 if (themeDisplay == null) {
651 return tokens;
652 }
653
654 tokens.put("cdn_host", themeDisplay.getCDNHost());
655 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
656 tokens.put("group_id", String.valueOf(groupId));
657 tokens.put("cms_url", themeDisplay.getPathContext() + "/cms/servlet");
658 tokens.put("image_path", themeDisplay.getPathImage());
659 tokens.put(
660 "friendly_url_private_group",
661 themeDisplay.getPathFriendlyURLPrivateGroup());
662 tokens.put(
663 "friendly_url_private_user",
664 themeDisplay.getPathFriendlyURLPrivateUser());
665 tokens.put(
666 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
667 tokens.put("main_path", themeDisplay.getPathMain());
668 tokens.put("portal_ctx", themeDisplay.getPathContext());
669 tokens.put(
670 "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
671 tokens.put("root_path", themeDisplay.getPathContext());
672 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
673
674
676 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
677 tokens.put(
678 "friendly_url_private",
679 themeDisplay.getPathFriendlyURLPrivateGroup());
680 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
681
682 return tokens;
683 }
684
685 public static String mergeLocaleContent(
686 String curContent, String newContent, String xsd) {
687
688 try {
689 SAXReader reader = new SAXReader();
690
691 Document curContentDoc = reader.read(new StringReader(curContent));
692 Document newContentDoc = reader.read(new StringReader(newContent));
693 Document xsdDoc = reader.read(new StringReader(xsd));
694
695 Element curContentRoot = curContentDoc.getRootElement();
696 Element newContentRoot = newContentDoc.getRootElement();
697 Element xsdRoot = xsdDoc.getRootElement();
698
699 curContentRoot.addAttribute(
700 "default-locale",
701 newContentRoot.attributeValue("default-locale"));
702 curContentRoot.addAttribute(
703 "available-locales",
704 newContentRoot.attributeValue("available-locales"));
705
706 Stack<String> path = new Stack<String>();
707
708 path.push(xsdRoot.getName());
709
710 _mergeLocaleContent(
711 path, curContentDoc, newContentDoc, xsdRoot,
712 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
713
714 curContent = formatXML(curContentDoc);
715 }
716 catch (Exception e) {
717 _log.error(e);
718 }
719
720 return curContent;
721 }
722
723 public static String removeArticleLocale(
724 String content, String languageId) {
725
726 try {
727 SAXReader reader = new SAXReader();
728
729 Document doc = reader.read(new StringReader(content));
730
731 Element root = doc.getRootElement();
732
733 String availableLocales = root.attributeValue("available-locales");
734
735 if (availableLocales == null) {
736 return content;
737 }
738
739 availableLocales = StringUtil.remove(availableLocales, languageId);
740
741 if (availableLocales.endsWith(",")) {
742 availableLocales = availableLocales.substring(
743 0, availableLocales.length() - 1);
744 }
745
746 root.addAttribute("available-locales", availableLocales);
747
748 removeArticleLocale(root, languageId);
749
750 content = formatXML(doc);
751 }
752 catch (Exception e) {
753 _log.error(e);
754 }
755
756 return content;
757 }
758
759 public static void removeArticleLocale(Element el, String languageId)
760 throws SystemException {
761
762 for (Element dynamicEl :
763 (List<Element>)el.elements("dynamic-element")) {
764
765 for (Element dynamicContentEl :
766 (List<Element>)dynamicEl.elements("dynamic-content")) {
767
768 String curLanguageId = GetterUtil.getString(
769 dynamicContentEl.attributeValue("language-id"));
770
771 if (curLanguageId.equals(languageId)) {
772 long id = GetterUtil.getLong(
773 dynamicContentEl.attributeValue("id"));
774
775 if (id > 0) {
776 ImageLocalUtil.deleteImage(id);
777 }
778
779 dynamicContentEl.detach();
780 }
781 }
782
783 removeArticleLocale(dynamicEl, languageId);
784 }
785 }
786
787 public static String removeOldContent(String content, String xsd) {
788 try {
789 SAXReader reader = new SAXReader();
790
791 Document contentDoc = reader.read(new StringReader(content));
792 Document xsdDoc = reader.read(new StringReader(xsd));
793
794 Element contentRoot = contentDoc.getRootElement();
795
796 Stack<String> path = new Stack<String>();
797
798 path.push(contentRoot.getName());
799
800 _removeOldContent(path, contentRoot, xsdDoc);
801
802 content = formatXML(contentDoc);
803 }
804 catch (Exception e) {
805 _log.error(e);
806 }
807
808 return content;
809 }
810
811 public static void removeRecentArticle(
812 PortletRequest req, String articleId) {
813
814 Stack<JournalArticle> stack = getRecentArticles(req);
815
816 Iterator<JournalArticle> itr = stack.iterator();
817
818 while (itr.hasNext()) {
819 JournalArticle journalArticle = itr.next();
820
821 if (journalArticle.getArticleId().equals(articleId)) {
822 itr.remove();
823
824 break;
825 }
826 }
827 }
828
829 public static void removeRecentStructure(
830 PortletRequest req, String structureId) {
831
832 Stack<JournalStructure> stack = getRecentStructures(req);
833
834 Iterator<JournalStructure> itr = stack.iterator();
835
836 while (itr.hasNext()) {
837 JournalStructure journalStructure = itr.next();
838
839 if (journalStructure.getStructureId().equals(structureId)) {
840 itr.remove();
841
842 break;
843 }
844 }
845 }
846
847 public static void removeRecentTemplate(
848 PortletRequest req, String templateId) {
849
850 Stack<JournalTemplate> stack = getRecentTemplates(req);
851
852 Iterator<JournalTemplate> itr = stack.iterator();
853
854 while (itr.hasNext()) {
855 JournalTemplate journalTemplate = itr.next();
856
857 if (journalTemplate.getTemplateId().equals(templateId)) {
858 itr.remove();
859
860 break;
861 }
862 }
863 }
864
865 public static String transform(
866 Map<String, String> tokens, String languageId, String xml,
867 String script, String langType)
868 throws TransformException, UnsupportedEncodingException {
869
870
872 if (_log.isDebugEnabled()) {
873 _log.debug("Language " + languageId);
874 }
875
876 if (_logTokens.isDebugEnabled()) {
877 String tokensString = PropertiesUtil.list(tokens);
878
879 _logTokens.debug(tokensString);
880 }
881
882 if (_logTransformBefore.isDebugEnabled()) {
883 _logTransformBefore.debug(xml);
884 }
885
886 List<TransformerListener> listenersList =
887 new ArrayList<TransformerListener>();
888
889 String[] listeners = PropsUtil.getArray(
890 PropsUtil.JOURNAL_TRANSFORMER_LISTENER);
891
892 for (int i = 0; i < listeners.length; i++) {
893 TransformerListener listener = null;
894
895 try {
896 if (_log.isDebugEnabled()) {
897 _log.debug("Instantiate listener " + listeners[i]);
898 }
899
900 boolean templateDriven = Validator.isNotNull(langType);
901
902 listener = (TransformerListener)Class.forName(
903 listeners[i]).newInstance();
904
905 listener.setTemplateDriven(templateDriven);
906 listener.setLanguageId(languageId);
907 listener.setTokens(tokens);
908
909 listenersList.add(listener);
910 }
911 catch (Exception e) {
912 _log.error(e, e);
913 }
914
915
917 if (_logXmlBeforeListener.isDebugEnabled()) {
918 _logXmlBeforeListener.debug(xml);
919 }
920
921 if (listener != null) {
922 xml = listener.onXml(xml);
923
924 if (_logXmlAfterListener.isDebugEnabled()) {
925 _logXmlAfterListener.debug(xml);
926 }
927 }
928
929
931 if (_logScriptBeforeListener.isDebugEnabled()) {
932 _logScriptBeforeListener.debug(script);
933 }
934
935 if (listener != null) {
936 script = listener.onScript(script);
937
938 if (_logScriptAfterListener.isDebugEnabled()) {
939 _logScriptAfterListener.debug(script);
940 }
941 }
942 }
943
944
946 String output = null;
947
948 if (Validator.isNull(langType)) {
949 output = xml;
950 }
951 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
952 output = JournalVmUtil.transform(tokens, languageId, xml, script);
953 }
954 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_XSL)) {
955 output = JournalXslUtil.transform(tokens, languageId, xml, script);
956 }
957
958
960 for (int i = 0; i < listenersList.size(); i++) {
961 TransformerListener listener = listenersList.get(i);
962
963
965 if (_logOutputBeforeListener.isDebugEnabled()) {
966 _logOutputBeforeListener.debug(output);
967 }
968
969 output = listener.onOutput(output);
970
971 if (_logOutputAfterListener.isDebugEnabled()) {
972 _logOutputAfterListener.debug(output);
973 }
974 }
975
976 if (_logTransfromAfter.isDebugEnabled()) {
977 _logTransfromAfter.debug(output);
978 }
979
980 return output;
981 }
982
983 private static void _mergeLocaleContent(
984 Stack<String> path, Document curDoc, Document newDoc, Element xsdEl,
985 String defaultLocale)
986 throws SystemException {
987
988 String elPath = "";
989
990 for (int i = 0; i < path.size(); i++) {
991 elPath += "/" + path.elementAt(i);
992 }
993
994 for (int i = 0; i < xsdEl.nodeCount(); i++) {
995 Node xsdNode = xsdEl.node(i);
996
997 if ((xsdNode instanceof Element) &&
998 (xsdNode.getName().equals("dynamic-element"))) {
999
1000 _mergeLocaleContent(
1001 path, curDoc, newDoc, (Element)xsdNode, defaultLocale,
1002 elPath);
1003 }
1004 }
1005 }
1006
1007 private static void _mergeLocaleContent(
1008 Stack<String> path, Document curDoc, Document newDoc, Element xsdEl,
1009 String defaultLocale, String elPath)
1010 throws SystemException {
1011
1012 String name = xsdEl.attributeValue("name");
1013
1014 String localPath = "dynamic-element[@name='" + name + "']";
1015
1016 String fullPath = elPath + "/" + localPath;
1017
1018 XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1019
1020 List<Element> curElements = xPathSelector.selectNodes(curDoc);
1021
1022 Element newEl = (Element)xPathSelector.selectNodes(newDoc).get(0);
1023
1024 if (curElements.size() > 0) {
1025 Element curEl = curElements.get(0);
1026
1027 List<Element> curDynamicContents = curEl.elements(
1028 "dynamic-content");
1029
1030 Element newContentEl = newEl.element("dynamic-content");
1031
1032 String newContentLanguageId = newContentEl.attributeValue(
1033 "language-id", StringPool.BLANK);
1034
1035 if (newContentLanguageId.equals(StringPool.BLANK)) {
1036 for (int k = curDynamicContents.size() - 1; k >= 0 ; k--) {
1037 Element curContentEl = curDynamicContents.get(k);
1038
1039 String curContentLanguageId = curContentEl.attributeValue(
1040 "language-id", StringPool.BLANK);
1041
1042 if ((curEl.attributeValue("type").equals("image")) &&
1043 (!curContentLanguageId.equals(defaultLocale) &&
1044 !curContentLanguageId.equals(StringPool.BLANK))) {
1045
1046 long id = GetterUtil.getLong(
1047 curContentEl.attributeValue("id"));
1048
1049 ImageLocalUtil.deleteImage(id);
1050 }
1051
1052 curContentEl.detach();
1053 }
1054
1055 curEl.content().add(newContentEl.createCopy());
1056 }
1057 else {
1058 boolean match = false;
1059
1060 for (int k = curDynamicContents.size() - 1; k >= 0 ; k--) {
1061 Element curContentEl = curDynamicContents.get(k);
1062
1063 String curContentLanguageId = curContentEl.attributeValue(
1064 "language-id", StringPool.BLANK);
1065
1066 if ((newContentLanguageId.equals(curContentLanguageId)) ||
1067 (newContentLanguageId.equals(defaultLocale) &&
1068 curContentLanguageId.equals(StringPool.BLANK))) {
1069
1070 curContentEl.detach();
1071
1072 curEl.content().add(k, newContentEl.createCopy());
1073
1074 match = true;
1075 }
1076
1077 if (curContentLanguageId.equals(StringPool.BLANK)) {
1078 curContentEl.addAttribute("language-id", defaultLocale);
1079 }
1080 }
1081
1082 if (!match) {
1083 curEl.content().add(newContentEl.createCopy());
1084 }
1085 }
1086 }
1087 else {
1088 xPathSelector = DocumentHelper.createXPath(elPath);
1089
1090 Element parentEl =
1091 (Element)xPathSelector.selectNodes(curDoc).get(0);
1092
1093 parentEl.content().add(newEl.createCopy());
1094 }
1095
1096 String type = xsdEl.attributeValue("type", StringPool.BLANK);
1097
1098 if (!type.equals("list") && !type.equals("multi-list")) {
1099 path.push(localPath);
1100
1101 _mergeLocaleContent(path, curDoc, newDoc, xsdEl, defaultLocale);
1102
1103 path.pop();
1104 }
1105 }
1106
1107 private static void _removeOldContent(
1108 Stack<String> path, Element contentEl, Document xsdDoc)
1109 throws SystemException {
1110
1111 String elPath = "";
1112
1113 for (int i = 0; i < path.size(); i++) {
1114 elPath += "/" + path.elementAt(i);
1115 }
1116
1117 for (int i = 0; i < contentEl.nodeCount(); i++) {
1118 Node contentNode = contentEl.node(i);
1119
1120 if (contentNode instanceof Element) {
1121 _removeOldContent(path, (Element)contentNode, xsdDoc, elPath);
1122 }
1123 }
1124 }
1125
1126 private static void _removeOldContent(
1127 Stack<String> path, Element contentEl, Document xsdDoc,
1128 String elPath)
1129 throws SystemException {
1130
1131 String name = contentEl.attributeValue("name");
1132
1133 if (Validator.isNull(name)) {
1134 return;
1135 }
1136
1137 String localPath = "dynamic-element[@name='" + name + "']";
1138
1139 String fullPath = elPath + "/" + localPath;
1140
1141 XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1142
1143 List<Element> curElements = xPathSelector.selectNodes(xsdDoc);
1144
1145 if (curElements.size() == 0) {
1146 contentEl.detach();
1147 }
1148
1149 path.push(localPath);
1150
1151 _removeOldContent(path, contentEl, xsdDoc);
1152
1153 path.pop();
1154 }
1155
1156 private static Log _log = LogFactory.getLog(JournalUtil.class);
1157
1158 private static Log _logOutputAfterListener = LogFactory.getLog(
1159 JournalUtil.class.getName() + ".OutputAfterListener");
1160
1161 private static Log _logOutputBeforeListener = LogFactory.getLog(
1162 JournalUtil.class.getName() + ".OutputBeforeListener");
1163
1164 private static Log _logScriptAfterListener = LogFactory.getLog(
1165 JournalUtil.class.getName() + ".ScriptAfterListener");
1166
1167 private static Log _logScriptBeforeListener = LogFactory.getLog(
1168 JournalUtil.class.getName() + ".ScriptBeforeListener");
1169
1170 private static Log _logTransfromAfter = LogFactory.getLog(
1171 JournalUtil.class.getName() + ".TransformAfter");
1172
1173 private static Log _logTransformBefore = LogFactory.getLog(
1174 JournalUtil.class.getName() + ".BeforeTransform");
1175
1176 private static Log _logTokens = LogFactory.getLog(
1177 JournalUtil.class.getName() + ".Tokens");
1178
1179 private static Log _logXmlAfterListener = LogFactory.getLog(
1180 JournalUtil.class.getName() + ".XmlAfterListener");
1181
1182 private static Log _logXmlBeforeListener = LogFactory.getLog(
1183 JournalUtil.class.getName() + ".XmlBeforeListener");
1184
1185}